阿里云提供的地理信息接口

https://datav.aliyun.com/tools/atlas/

有两个接口, 一个是[行政编码].json, 一个是[行政编码]_full.json, 从接口中可以提取到区县一级的行政区划信息. 提取的过程中遇到的一些问题:

  • 从[行政编码].json中读取的信息中, 可能parent = null, 出现这种情况的大都是一些撤县改区的节点, 要将其设为上一级节点的行政编码
  • 从[行政编码].json中读到的parent的adcode, 可能与[父节点行政编码]_full.json中读到的parent的adcode不一致, 例如从110000_full.json中得到的节点列表, 其parent都是110000, 但是在取其字节点110101.json时会发现, parent变成了110100, 这时候要使用110100这个行政编码
  • 因为从上至下遍历时, 是不会遇到110100这个节点的, 所以在遍历的过程中, 要检查是否出现了未知的行政编码, 如果有, 需要额外读取并入库
  • 有部分节点, 其json无法读取(不存在), 例如密云110118.json, 延庆110119.json, 这时候要用前一步得到的信息入库

使用生成的行政区划数据时, 对于香港澳门的数据, 因为没有level=city的这一级, 所以需要特殊处理一下, 例如在读取province这一级的子节点时, 如果发现没有level=city的节点, 那么就返回一个虚拟的节点, 这个节点各字段值和自己一样, 但是level=city.

#!/usr/bin/python3
# -*- coding: UTF-8 -*- import json
import traceback
import rbcommon def readRegion(adcode, parent_code = None):
# https://geo.datav.aliyun.com/areas/bound/140000.json
url = 'https://geo.datav.aliyun.com/areas/bound/' + adcode + '.json'
print(url)
echo = rbcommon.requestGet(url, 'UTF-8', 20, 10)
if echo is None:
print('URL request failed: ' + url)
return
elif echo.find('<?') == 0:
print('Not found: ' + url)
return
# print(echo)
json_obj = json.loads(echo)
region = {}
region['name'] = json_obj['features'][0]['properties']['name']
region['adcode'] = json_obj['features'][0]['properties']['adcode']
region['telecode'] = json_obj['features'][0]['properties']['telecode']
level = json_obj['features'][0]['properties']['level']
if (level == 'country'):
region['level'] = 0
elif (level == 'province'):
region['level'] = 1
elif (level == 'city'):
region['level'] = 2
elif (level == 'district'):
region['level'] = 3
if ('parent' in json_obj['features'][0]['properties']) and (not json_obj['features'][0]['properties']['parent'] is None):
region['parent'] = json_obj['features'][0]['properties']['parent']['adcode']
else:
region['parent'] = parent_code # read sub regions
sub_regions = []
region['children'] = sub_regions
# https://geo.datav.aliyun.com/areas/bound/140000_full.json
url = 'https://geo.datav.aliyun.com/areas/bound/' + adcode + '_full.json'
print(url)
echo = rbcommon.requestGet(url, 'UTF-8', 20, 10)
if echo is None:
print('URL request failed: ' + url)
return region
elif echo.find('<?') == 0:
print('Not found: ' + url)
return region
# print(echo)
json_obj = json.loads(echo)
sub_objs = json_obj['features']
for sub_obj in sub_objs:
sub_region = {}
sub_region['adcode'] = (str)(sub_obj['properties']['adcode'])
if (sub_region['adcode'] == region['adcode']):
continue
sub_region['name'] = sub_obj['properties']['name']
sub_region['telecode'] = None
level = sub_obj['properties']['level']
if (level == 'country'):
sub_region['level'] = 0
elif (level == 'province'):
sub_region['level'] = 1
elif (level == 'city'):
sub_region['level'] = 2
elif (level == 'district'):
sub_region['level'] = 3
sub_region['parent'] = adcode
sub_regions.append(sub_region) # further check if the parent adcode is correct
if (len(sub_regions) > 0):
# https://geo.datav.aliyun.com/areas/bound/140000.json
url = 'https://geo.datav.aliyun.com/areas/bound/' + sub_regions[0]['adcode'] + '.json'
# print(url)
echo = rbcommon.requestGet(url, 'UTF-8', 20, 10)
if echo is None:
print('URL request failed: ' + url)
elif echo.find('<?') == 0:
print('Not found: ' + url)
else:
json_obj = json.loads(echo)
if ('parent' in json_obj['features'][0]['properties']) and (not json_obj['features'][0]['properties']['parent'] is None):
dummy_parent = json_obj['features'][0]['properties']['parent']['adcode']
if (dummy_parent != sub_regions[0]['parent']):
print('Update parent from {} to {}', sub_regions[0]['parent'], dummy_parent)
for sub_region in sub_regions:
sub_region['parent'] = dummy_parent return region def readAllRegion(parent_region):
region = readRegion(parent_region['adcode'], parent_region['parent'])
if not region is None:
if (not region['parent'] is None) and (not region['parent'] in regions):
new_region = readRegion(region['parent'], parent_region['parent'])
if not new_region is None:
regions.add(new_region['adcode'])
insert(new_region) regions.add(region['adcode'])
insert(region) for sub_region in region['children']:
readAllRegion(sub_region)
else:
regions.add(parent_region['adcode'])
insert(parent_region) def insert(region):
try:
with rbcommon.mysqlclient.cursor() as cursor:
sql = 'INSERT IGNORE INTO `s_region` (`id`, `parent_id`, `level`, `name`, `tele_code`, `short_name`, ' \
'`full_name`) VALUES (%s, %s, %s, %s, %s, %s, %s)'
cursor.execute(sql, (
region['adcode'],
None if (not 'parent' in region) else region['parent'],
region['level'],
region['name'],
region['telecode'],
region['name'],
'{}'))
rbcommon.mysqlclient.commit()
except Exception as e:
print(json.dumps(region))
traceback.print_exc() ### MAIN ###
regions = set()
region = readRegion('100000')
readAllRegion(region)

其中rbcommon.mysqlclient的初始化方法

mysqlclient = pymysql.connect(
host=cfg['mysql']['host'],
port=cfg['mysql']['port'],
user=cfg['mysql']['user'],
password=cfg['mysql']['password'],
db=cfg['mysql']['db'],
charset=cfg['mysql']['charset'],
cursorclass=pymysql.cursors.DictCursor)

  

从阿里云DATAV GeoAtlas接口抽取行政区划数据的更多相关文章

  1. php与阿里云短信接口接入

    使用阿里云短信API,需要在控制台获取以下必要参数,其中需要自己手机验证+官方审核多次,尤其审核需要保持耐心. 1. accessKeyId  相当于你的个人账户密钥: 2. accessKeySec ...

  2. 阿里云DNS api接口 shell 更改DNS解析

    可定时任务检查域名解析,调用alidns.sh更新DNS解析 #!/bin/bash # alidns.sh #https://www.cnblogs.com/elvi/p/11663910.html ...

  3. 大型可视化项目用什么工具好呢?——不如了解一下阿里云DataV尊享版

    随着信息化的发展和进步,可视化大屏开始为社会各行业提供全面应用.目前越来越多的需求显示希望大屏能够更直观的还原出所要展示数据可视化的真实场景,让整个项目更立体.更有科技感,让项目在面对复杂操作时能灵活 ...

  4. 【阿里云产品公测】大数据下精确快速搜索OpenSearch

    [阿里云产品公测]大数据下精确快速搜索OpenSearch 作者:阿里云用户小柒2012 相信做过一两个项目的人都会遇到上级要求做一个类似百度或者谷歌的站内搜索功能.传统的sql查询只能使用like ...

  5. THINKPHP3.2.3增加阿里云短信接口思路整理

    https://help.aliyun.com/document_detail/55359.html?spm=5176.product44282.4.7.O4lc1n 阿里云短信服务地址,感冒的下载看 ...

  6. 阿里云DataV专业版发布,为可视化创造更多可能!

    阿里云数据可视化应用工具DataV正式推出专业版,该版本为可视化领域专业团队和从业者量身打造,定位数据可视分析大屏搭建场景,让使用者可以轻松hold住复杂交互设计和实时数据交互查询需求. 什么是Dat ...

  7. 阿里云短信接口开发实践(Java

    随着互联网的兴起,各行各业的需求都在不断的增加.随着业务的扩大,企业给用户发送短信验证码的业务,也是如火如荼.在这里,calvin给各位开发者推荐阿里云短信平台.原因有二:1.接入较简单,开发成本低 ...

  8. TP5整合的阿里云短信接口

    现阶段,短信的应用主要就是用来验证下手机号是不是正常的手机号.只要涉及到用户手机号的问题的时候,都会做短信验证码来验证下改手机号是否是正常手机号.接下来就是操作步骤. 首先要在阿里云账号上开通短信功能 ...

  9. thinkphp5.1 阿里云短信接口

    1.首先声明,我个人是没有,accessKeyId    accessKeySecret   SignName     TemplateCode这些参数是需要自己去,阿里云注册,生成的. 我用的密钥( ...

随机推荐

  1. httpclient工具类,post请求发送json字符串参数,中文乱码处理

    在使用httpclient发送post请求的时候,接收端中文乱码问题解决. 正文: 我们都知道,一般情况下使用post请求是不会出现中文乱码的.可是在使用httpclient发送post请求报文含中文 ...

  2. 【RAC】 RAC For W2K8R2 安装--卸载(八)

    [RAC] RAC For W2K8R2 安装--卸载(八) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它 ...

  3. mysql多实例启动过程

    单机多实例,是基本的测试环境 01.myslq提供单机管理多节点 02.启动mysql多实例 03.观察进程

  4. 洛谷 P1816 忠诚题解

    题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...

  5. 代码优化 - 求数组中的第 K 个最大元素

    题目要求: 解法一: 直接用 sort 从大到小排序,取第 k 个 var findKthLargest = function (nums, k) { nums.sort((a, b) => { ...

  6. Kotlin属性引用进阶与构造方法引用

    继续还是探讨Kotlin反射相关的知识点,说实话这块不是太好理解,待在实际工作中去对它进行实践慢慢来加深印象. 属性引用进阶: 在Kotlin中的反射其实是跟Java的反射有对应关系的,具体相关的定义 ...

  7. zookeeper题目

    1. ZooKeeper是什么?2. ZooKeeper提供了什么?3. Zookeeper文件系统4. ZAB协议?5. 四种类型的数据节点 Znode6. Zookeeper Watcher 机制 ...

  8. 记录一下使用element ui使用级联选择器的坑,级联选择器的默认选中

    Cascader 级联选择器 使用级联选择器我使用的是默认选中值 下面是我的数据格式,只是形式相同,值不同, 后台的数据是这样的不是ID //级联选择器 <el-cascader :props= ...

  9. centos7部署inotify与rsync实现实时数据同步

    实验环境:CentOS Linux release 7.6.1810 node1:192.168.216.130 客户端(向服务端发起数据同步) node2:192.168.216.132 服务端(接 ...

  10. Discrete Cosine Transform

    离散余弦变换 由于实信号傅立叶变换的共轭对称性,导致DFT后在频域中有一半的数据冗余.离散余弦变换(DCT)在处理实信号时比离散傅立叶(DFT)变换更具优势.在处理声音信号这类实信号时,DFT得到的结 ...