首页 > 解决方案 > 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')

标签: djangopostgisgeojsongeopandasfolium

解决方案


您的 GeoDataFramegdf在除活动几何之外的另一列中包含 LineString 几何。GeoPandas 目前(从 0.9.0 开始)无法将这些转换为 JSON(请参阅此错误报告https://github.com/geopandas/geopandas/issues/1906)。您需要先删除受影响的列,然后再将其传递给您folium自己或将其转换为其他内容。


推荐阅读