定制powerbi形状地图——geojson编辑后转topojson格式

关于powerbi形状地图
设置
文件>选项>预览功能>形状映射视觉对象
添加自定义地图
拖入形状地图>加个字段或度量值>格式>形状>自定义地图
这里的自定义地图需要topojson格式,并且带有“地图键”,后面详细说明
接下来我们制作自己需要的地图文件(用geojson编写后转成topojson格式)
什么是geojson 和topojson格式
参考链接1:http://geojson.org/
参考链接2:https://www.jianshu.com/p/dbdc7d4609e6
上文中提到过,powerbi中需要的是带有“地图键”的topojson格式,那么如果是geojson,第一个type类型应该是“FeatureCollection”
接下来获取带有中国行政边界线的地图代码
网上找了很久,找到一个网站
https://gadm.org/download_country_v3.html
(该网站把台湾作为country,已留言不知道有没有用)
选择china,点击shapefile 下载地图文件包
文件比较多,用的是shp文件,
文件 | 说明 |
---|---|
gadm36_CHN_0.shp | 中国大陆地图 |
gadm36_CHN_1.shp | 中国大陆(含省份边界) |
gadm36_CHN_2.shp | 中国大陆(含地级市边界) |
gadm36_CHN_3.shp | 中国大陆(含区县边界) |
选择含有省份边界的gadm36_CHN_1.shp
在这个网站转成geojson格式,方便编辑:https://mapshaper.org/
select 选择文件>import导入>export导出 选择geojson
再下载一个台湾地图,同理操作(否则可是政治错误。)
两个加起来就得到我们需要的含有边界的完整中国geojson格式地图代码
分析geojson格式
因为地图数据文件很大,用notepad++打开经常会卡死,分析结构比较麻烦,写了一个简单的python来看一下结构:
import json
def get_json(path):
json_data = ""
with open(path,"r",encoding="utf-8") as json_file:
for line in json_file.readlines():
json_data = json_data + line
data = json.loads(json_data)
return data
上面得到的数据结构如下:
几何体集合 GeometryCollection
- “type”:“GeometryCollection”
- “geometries”: [geometry_list]
- “type”:“MultiPolygon”
- “coordinates”:[coordinates_list] N个层级
要转成FeatureCollection
- “type”:“FeatureCollection”
- “features”: [feature_list]
- “type”:“Feature”
- “geometry”:
- “type”: 需要根据上面的决定
- “coordinates”:[coordinates_list]
- “properties”:
- “PROVINCE”:“xxx”
- “id”:“xx”
用Python写代码编辑geojson
import json
import requests
# 获取数据代码
def get_json(path):
json_data = ""
with open(path,"r",encoding="utf-8") as json_file:
for line in json_file.readlines():
json_data = json_data + line
data = json.loads(json_data)
return data
# 将geojson主type类改为FeatureCollection 并将含有地图边界的数据以及省份数据添加进去
def change_json(adress_dic):
features_list = []
for id in adress_dic:
adress_= adress_dic[id][2]
features_dic = {"type":"Feature",
"geometry":
{"type":adress_dic[id][1],
"coordinates":adress_},
"properties":
{"PROVINCE":adress_dic[id][0],
"id":id}
}
features_list.append(features_dic)
json_dic = {"type":"FeatureCollection",
"features":features_list}
return json_dic
# 调用高德地图API接口,用逆向地理编码,通过经纬度,返回省份地级市结果
def get_city(location):
url_basic = "https://restapi.amap.com/v3/geocode/regeo"
url_api = url_basic+"?"+"key=xxxxxxx"+"&location="+location #用自己的key,参考高德地图开放API接口
response = requests.get(url_api)
text_dic = json.loads(response.text)
result_dic = {}
result_dic["province"] = text_dic["regeocode"]["addressComponent"]["province"]
return result_dic
# 获取两个geojson的地理数据
data_1 = get_json("D:/KeepLearning/map/china_TW_geo.json")
geometry_list_1 = data_1["geometries"]
data_2 = get_json("D:/KeepLearning/map/china_withoutTW_1_geo.json")
geometry_list_2 = data_2["geometries"]
geometry_list = geometry_list_1 + geometry_list_2
if __name__ == "__main__":
adress_dic = {}
id = 1
for i in geometry_list:
if i["type"] == "Polygon":
location_list =i["coordinates"][0][0]
if i["type"] == "MultiPolygon":
location_list =i["coordinates"][0][0][0]
location = "%s,%s" %(round(location_list[0],5),round(location_list[1],5))
result_dic = get_city(location)
province = result_dic["province"]
adress_dic[id] = [province,i["type"],i["coordinates"]]
id += 1
json_dic = change_json(adress_dic)
with open("D:/KeepLearning/map/chinamap_province_geo.json","w",encoding= "utf-8") as json_file:
json_file.writelines(json.dumps(json_dic)+"\n")
然后得到chinamap_province_geo.json 文件,在刚才的网站中转换成topojson格式,
定制完成。
可以通过选择地图中的某些省份,进行数据筛选联动。
通过以上步骤,还可以生成某些省份,或者某些地级市,区县的详细地图。