使用python在scattermapbox中的点周围绘制一个多边形

编程入门 行业动态 更新时间:2024-10-26 22:29:40
本文介绍了使用python在scattermapbox中的点周围绘制一个多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

I am using plotlys scattermapbox to plot points on a map. I'd like to draw the polygon that cover 'x' mile radius from a POI.

dcc.Graph(id="map-graph"), @application.callback([ Output("map-graph", "figure"), ], [ Input("address", "value"), Input("type", "value") ] ) def update_graph(address, type): for i, row in df.iterrows(): lat = row["Lat"] lng = row["Long"] data.append({ "type": "scattermapbox", "lat": [lat], "lon": [lng], "name": "Location", "showlegend": False, "hoverinfo": "text", "mode": "markers", "marker": { "symbol": "circle", "size": 8, "opacity": 0.8, "color": "black" } } ) # Plot POI POI_Lat = 37.785908 POI_Long = -122.400803 data.append({ "type": "scattermapbox", "lat": [POI_Lat], "lon": [POI_Long], "marker": { "symbol": "circle, "size": 28, "opacity": 0.7, "color": "rgb(128, 128, 128)" } } )

df is a pandas dataframe that includes coordinates for locations within x miles of POI. How do I update the map-graph to draw a polygon that covers all the points?

Adding a layer to layout dictionary:

gdf = circles(Lat, Long, radius=1609.34) print(gdf['geometry'][0]) POLYGON ((385272.0167249573 3768678.19769511, 385264.2673129799 3768520.454790493,.......)) layout = { "autosize": True, "hovermode": "closest", "mapbox": { "accesstoken": MAPBOX_KEY, "bearing": 0, "center": { "lat": layout_lat, "lon": layout_lon }, "layers": [ { "source": json.loads(gdf.geometry.to_json()), "below": "traces", "type": "line", "color": "purple", "line": {"width": 1.5}, } ], "pitch": 0, "zoom": zoom, "style": "outdoors", }, "margin": { "r": 0, "t": 0, "l": 0, "b": 0, "pad": 0 } }

解决方案

  • based on answer to this duplicate question Obtain coordinates of a Polygon / Multi-polygon around a point in python
  • no sample data provided in question, so I've used UK hospital data
  • have created a helper function poi_poly(). NB radius is in meters as per UTM geometry
  • UTM geometry is used to create a polygon of specified radius
  • markers are then intersected with this polygon. Then get the convex hull
  • have provided option to return radius polygon as well, in example below I've returned this to demonstrate that the convex hull polygon is within the radius of the POI

import shapely.geometry import pandas as pd import geopandas as gpd import requests, io, json import plotly.express as px import random def poi_poly( df, radius=10 ** 5, poi={"Longitude": 0.06665166467428207, "Latitude": 51.19034957885742}, lon_col="Longitude", lat_col="Latitude", include_radius_poly=False, ): # generate a geopandas data frame of the POI gdfpoi = gpd.GeoDataFrame( geometry=[shapely.geometry.Point(poi["Longitude"], poi["Latitude"])], crs="EPSG:4326", ) # extend point to radius defined (a polygon). Use UTM so that distances work, then back to WSG84 gdfpoi = ( gdfpoi.to_crs(gdfpoi.estimate_utm_crs()) .geometry.buffer(radius) .to_crs("EPSG:4326") ) # create a geopandas data frame of all the points / markers if not df is None: gdf = gpd.GeoDataFrame( geometry=df.loc[:, ["Longitude", "Latitude"]] .dropna() .apply( lambda r: shapely.geometry.Point(r["Longitude"], r["Latitude"]), axis=1 ) .values, crs="EPSG:4326", ) else: gdf = gpd.GeoDataFrame(geometry=gdfpoi) # create a polygon around the edges of the markers that are within POI polygon return pd.concat( [ gpd.GeoDataFrame( geometry=[ gpd.sjoin( gdf, gpd.GeoDataFrame(geometry=gdfpoi), how="inner" ).unary_union.convex_hull ] ), gpd.GeoDataFrame(geometry=gdfpoi if include_radius_poly else None), ] ) # get some public addressess - hospitals. data that can be scattered dfhos = pd.read_csv( io.StringIO( requests.get("media.nhschoices.nhs.uk/data/foi/Hospital.csv").text ), sep="¬", engine="python", ) # generate polygon of markers within 5 mile radius of Point of Interest poi = dfhos.loc[random.randint(0, len(dfhos) - 1), ["Longitude", "Latitude"]].to_dict() gdf = poi_poly(dfhos, poi=poi, radius=1609.34 * 5, include_radius_poly=True) fig = ( px.scatter_mapbox( dfhos, lat="Latitude", lon="Longitude", color="Sector", hover_data=["OrganisationName", "Postcode"], ) .update_traces(marker={"size": 10}) .update_layout( mapbox={ "style": "open-street-map", "zoom": 9, "center": {"lat": poi["Latitude"], "lon": poi["Longitude"]}, "layers": [ { "source": json.loads(gdf.geometry.to_json()), "below": "traces", "type": "line", "color": "purple", "line": {"width": 1.5}, } ], }, margin={"l": 0, "r": 0, "t": 0, "b": 0}, ) ) fig.show()

draw just a circle polygon
  • poi_poly() has been updated. DataFrame is no longer mandatory for finding markers within POI
  • simple example of creating a circle (actually a polygon) centred on a single set of GPS co-ordinates

import plotly.graph_objects as go poi = {"Latitude": 37.785908, "Longitude": -122.400803} go.Figure(go.Scattermapbox()).update_layout( mapbox={ "style": "open-street-map", "zoom": 9, "center": {"lat": poi["Latitude"], "lon": poi["Longitude"]}, "layers": [ { "source": json.loads(poi_poly(None, poi=poi, radius=1609).to_json()), "below": "traces", "type": "line", "color": "purple", "line": {"width": 1.5}, } ], }, margin={"l": 0, "r": 0, "t": 0, "b": 0}, )

更多推荐

使用python在scattermapbox中的点周围绘制一个多边形

本文发布于:2023-08-02 00:07:28,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1272916.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多边形   python   scattermapbox

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!