I have a radius and centroid (lan=114, long=22) and I would like to plot a circle on a map to show the area impacted. On top of the circle, I want to add an arrow to show the radius. Something like this but on a map.
I found these codes from Plotly python Problem with adding shape to maps
I tried to modify it to my centroid but I am unfamiliar with plotting on a map as it isn't using the add_shape. Any help is appreciated.
import plotly.express as px
import geopandas as gpd
import numpy as np
import pandas as pd
df = px.data.election()
# prep geometry
gdf = gpd.GeoDataFrame.from_features(px.data.election_geojson())
gdf = gdf.join(
gdf["geometry"].centroid.apply(lambda g: pd.Series({"lon": g.x, "lat": g.y}))
)
# plot circles at various lat / lon
fig = px.scatter_mapbox(
df.merge(gdf, on="district"), lat="lat", lon="lon", size="total"
).update_layout(mapbox={"style": "carto-positron"})
# generate a 10000m circle at a random black as geojson
cgeo = (
gdf.set_crs("epsg:4326")
.sample(1)
.pipe(lambda d: d.to_crs(d.estimate_utm_crs()))["geometry"]
.centroid.buffer(10000)
.to_crs("epsg:4326")
.__geo_interface__
)
# add circle geometry as layer to mapbox figure
fig.update_layout(
mapbox={
"layers": [
{"source": cgeo, "color": "PaleTurquoise", "type": "fill", "opacity":.5},
]
}
)
LineString
import plotly.express as px
import geopandas as gpd
import numpy as np
import pandas as pd
from shapely.geometry import LineString
df = px.data.election()
# prep geometry
gdf = gpd.GeoDataFrame.from_features(px.data.election_geojson())
gdf = gdf.join(
gdf["geometry"].centroid.apply(lambda g: pd.Series({"lon": g.x, "lat": g.y}))
)
# plot circles at various lat / lon
fig = px.scatter_mapbox(
df.merge(gdf, on="district"), lat="lat", lon="lon", size="total"
).update_layout(mapbox={"style": "carto-positron"})
gdf_ = gdf.set_crs("epsg:4326").sample(1)
utm = gdf_.estimate_utm_crs()
gdf_ = gdf_.to_crs(utm)
b = 10000
m = b // 10
p = gdf_.centroid.values[0]
arrow = LineString(
[p, (p.x + b, p.y), (p.x + b - m, p.y - m), (p.x + b - m, p.y + m), (p.x + b, p.y)]
)
def geojson(shape, utm):
return gpd.GeoSeries([shape], crs=utm).to_crs("epsg:4386").__geo_interface__
# add circle geometry as layer to mapbox figure
fig.update_layout(
mapbox={
"layers": [
{
"source": geojson(p.buffer(b), utm),
"color": "PaleTurquoise",
"type": "fill",
"opacity": 0.5,
},
{
"source": geojson(p.buffer(m), utm),
"color": "red",
"type": "fill",
"opacity": 0.5,
},
{
"source": geojson(arrow, utm),
"color": "blue",
"type": "line",
"opacity": 0.5,
},
]
}
)