django - LineString 类型的对象不是 JSON 可序列化的
问题描述
使用 folium.GeoJSON 时如何找出此错误。gdf 是一个地理数据框。我也试过 gdf.to_json() 但它不起作用。我正在使用 postgresql 数据库(postgis)在 django 环境中工作。地理数据框 gdf 是从 geojson 文件转换而来的。现在我收到以下错误“'NoneType' 对象不可下标”。
def retrieve_data_from_postgres(network_id,
set_initial_crs=4326,
zone_radius=15,
intersection_radius_percentage=0.8,
distance_offset_percentage=0.8,
line_color='orange',
link_side='right',
):
initial_crs = "EPSG:{}".format(set_initial_crs)
initial_crs = CRS(initial_crs)
CRS84 = "EPSG:4326"
default_crs = "EPSG:3857"
edges = Edge.objects.filter(network_id=network_id)
edges = serialize('geojson', edges,
fields=('id', 'param1', 'param2', 'param3', 'speed', 'length',
'lanes','geometry', 'name', 'source', 'target','network', 'road_type'))
edges = json.loads(edges)
edges_gdf = gpd.GeoDataFrame.from_features(edges['features']) # Convert a geojson as geodataframe
nodes = Node.objects.filter(network_id=network_id).values()
nodes_df = pd.DataFrame(nodes)
nodes_df['location'] = nodes_df['location'].apply(geometry.Point)
nodes_gdf = gpd.GeoDataFrame(nodes_df, geometry=nodes_df['location'])
edges_gdf.set_crs(initial_crs, inplace=True)
nodes_gdf.set_crs(initial_crs, inplace=True)
nodes_gdf.to_crs(CRS84, inplace=True)
zone_radius = zone_radius
intersection_radius = intersection_radius_percentage * zone_radius
distance_offset = distance_offset_percentage * zone_radius
tiles_layer = 'OpenStreetMap'
G = nx.from_pandas_edgelist(edges_gdf, 'source', 'target',
['speed', 'length', 'lanes', 'name', 'geometry'],
create_using=nx.MultiDiGraph())
# Add oneway column (it is a boolean column)
for u, v, d in G.edges(keys=False, data=True):
if G.has_edge(v, u):
G.edges[u, v, 0]['oneway'] = False
else:
G.edges[u, v, 0]['oneway'] = True
df_graph_to_pandas = nx.to_pandas_edgelist(G, source='source', target='target')
gdf = gpd.GeoDataFrame(df_graph_to_pandas, geometry='geometry')
gdf.set_crs(CRS84, inplace=True)
# On convertit en metre (m) avant d'appliquer le décalage afin
# d'uniformiser car parallel_offset se calcule en (m)
gdf.to_crs(crs=default_crs, inplace=True)
# Define parallel offset Geoserie
# geometry to offset and column it depends on
col_list = ['geometry', 'oneway']
gdf['_offset_geometry_'] = gdf[col_list].apply(
lambda x: x['geometry'].parallel_offset(
distance_offset, link_side) if not x['oneway']
else x['geometry'].parallel_offset(0, link_side),
axis=1)
# Drop old geometry and replace it by _offset_geometry_
gdf.drop('geometry', axis=1, inplace=True)
gdf.set_geometry('_offset_geometry_', inplace=True)
gdf.set_crs(default_crs, inplace=True)
# Converting back in 4326 before ploting
gdf.to_crs(crs=CRS84, inplace=True)
latitudes = list(nodes_gdf['geometry'].y)
longitudes = list(nodes_gdf['geometry'].x)
# Initialize the map
m = folium.Map(location=[latitudes[0], longitudes[0]],
max_zoom=18, prefer_canvas=True, tiles=tiles_layer)
print(gdf.columns)
layer=folium.GeoJson(
gdf,
tooltip=folium.GeoJsonTooltip(fields=['oneway','lanes',
'length','speed','name'],localize=True),
style_function=lambda x: {
'color': line_color
}).add_to(m)
# Bounding box the map such that the network is entirely center and visible
m.fit_bounds(layer.get_bounds())
# Adding the nodes points
for lat, long in list(zip(latitudes, longitudes)):
folium.Circle(location=[lat, long], color='cyan', fill=True,
fill_opacity=1,radius=intersection_radius).add_to(m)
m.save('templates/visualization.html')
解决方案
您的 GeoDataFramegdf
在除活动几何之外的另一列中包含 LineString 几何。GeoPandas 目前(从 0.9.0 开始)无法将这些转换为 JSON(请参阅此错误报告https://github.com/geopandas/geopandas/issues/1906)。您需要先删除受影响的列,然后再将其传递给您folium
自己或将其转换为其他内容。
推荐阅读
- bigdata - write.xlsx 用于基因组数据
- sql - SQL Count of the same country,相同的名字,相同的姓氏的人相同的年龄(例如史密斯)
- javascript - 电子 ondrop 和 ondrag- 事件未触发
- c - cs50 pset4 - 边缘检测过滤器不起作用 - sobel 算子
- python - Kivy using Canvas: Key error with line while starting beyond boundaries
- inno-setup - Inno Setup:如何调整下部窗格区域的大小?
- c++ - 模板类中的 C++ 嵌套类
- javascript - 在 JavaScript 中链接 URL
- python-3.x - 将一项任务的输出发送到气流中的另一项任务
- php - 子域分组错过了 laravel 中的斜线