我一直在尝试在Plotly中通过转换shapefiles从 https:/geoportal.statistics.gov.ukdatasetslocal-authority-districts-december-2019-boundaries-uk-bfc。.
Python Plotly docs for plotly.graph_objects.Choroplethmapbox
在geoJSON中提到 id
字段是每个特征都需要的。我既尝试了创建一个人工的 id
并使用图利 featurekeyid
字段,但它们都没有工作。当我使用 id
钥匙,我已经检查了 id
键是否在正确的位置,并尝试了int64和字符串。
有时,基本的mapbox层会呈现,但没有多边形,而其他的代码会运行,然后挂起。
我也试过用mapshaper的各种算法减小.shp文件的大小,然后保存为geoJSON格式,并跳过Python中从.shp到geoJSON的转换步骤,但同样没有用。同时也改变了 tolerance
在 shapely
的操作似乎并没有改变输出。
我所期望的是一个地图投影,其底层为mapbox,上面有地方当局的区域多边形,并已填充。下面的链接显示了这些多边形,是在 mapshaper.org 上创建的。
我的mapbox访问令牌是有效的。
这是一个通过在地图中添加 id
字段,并将.shp文件转换为geoJSON,然后创建跟踪。
import geopandas as gpd
from shapely.geometry import LineString, MultiLineString
import plotly.graph_objs as go
# load in shp files
lad_shp = gpd.read_file('zip://../../data/external/Local_Authority_Districts_(December_2019)_Boundaries_UK_BFC-shp.zip', encoding='utf-8')
# using empet code to convert .shp to geoJSON
def shapefile_to_geojson(gdf, index_list, tolerance=0.025):
# gdf - geopandas dataframe containing the geometry column and values to be mapped to a colorscale
# index_list - a sublist of list(gdf.index) or gdf.index for all data
# tolerance - float parameter to set the Polygon/MultiPolygon degree of simplification
# returns a geojson type dict
geo_names = list(gdf[f'lad19nm']) # name of authorities
geojson = {'type': 'FeatureCollection', 'features': []}
for index in index_list:
geo = gdf['geometry'][index].simplify(tolerance)
if isinstance(geo.boundary, LineString):
gtype = 'Polygon'
bcoords = np.dstack(geo.boundary.coords.xy).tolist()
elif isinstance(geo.boundary, MultiLineString):
gtype = 'MultiPolygon'
bcoords = []
for b in geo.boundary:
x, y = b.coords.xy
coords = np.dstack((x,y)).tolist()
bcoords.append(coords)
else: pass
feature = {'type': 'Feature',
'id' : index,
'properties': {'name': geo_names[index]},
'geometry': {'type': gtype,
'coordinates': bcoords},
}
geojson['features'].append(feature)
return geojson
geojsdata = shapefile_to_geojson(lad_shp, list(lad_shp.index))
# length to generate synthetic data for z attribute
L = len(geojsdata['features'])
# check id key is there
geojsdata['features'][0].keys()
>> dict_keys(['type', 'id', 'properties', 'geometry'])
# example of authroity name
geojsdata['features'][0]['properties']['name']
>> 'Hartlepool'
# check id
k=5
geojsdata['features'][k]['id']
>> '5'
trace = go.Choroplethmapbox(z=np.random.randint(10, 75, size=L), # synthetic data
locations=[geojsdata['features'][k]['id'] for k in range(L)],
colorscale='Viridis',
colorbar=dict(thickness=20, ticklen=3),
geojson=geojsdata,
text=regions,
marker_line_width=0.1, marker_opacity=0.7)
layout = go.Layout(title_text='UK LAD Choropleth Demo',
title_x=0.5,
width=750,
height=700,
mapbox=dict(center=dict(lat=54, lon=-2),
accesstoken=mapbox_access_token,
zoom=3))
fig=go.Figure(data=[trace], layout =layout)
fig.show()
从上面的geoJSON输出 shapefile_to_geojson
函数可以在这里找到。https:/www.dropbox.comsvuf3jtrr2boq5eglad19-geo.json?dl=0
有人知道是什么原因导致了这个问题吗?我假设.shp文件是好的,因为它们在mapshaper.org和QGis上渲染得很好。任何帮助将是非常感激的。
谢谢您的帮助。
简单地改变投影系统就能纠正错误。在转换为geoJSON之前进行。
lad_shp = lad_shp.to_crs(epsg=4326)