Hey Arpit,
Welcome to plotly here are some useful references for what you’ve described in this post.
For setting up boundaries you could use this to get a geojson of just india that would work within dash leaflet:
Then you can refrence this code to get an idea of how to set the layer, create a custom icon, change the size of said icon allow on click with map to display icon and showcase the icon only if its used within the layered borders you’ve setup:
# Open and load the GeoJSON file
with open('assets/region_borders/dev.geo.json', 'r', encoding='utf-8') as file:
dev_borders = json.load(file)
# check if point is within geojson area
def is_point_in(lat, lon, geojson=dev_borders):
if not isinstance(geojson, dict) or 'features' not in geojson:
raise ValueError("GeoJSON must be a dictionary with a 'features' key.")
# Correct the order of lat and lon when creating the Point
point = Point(lon, lat) # Use (longitude, latitude)
# Create a GeoDataFrame from the GeoJSON features
gdf = gpd.GeoDataFrame.from_features(geojson['features'])
# Check if the point is within any of the geometries in the GeoDataFrame
is_within = gdf.contains(point).any()
return is_within
map_context = [
dl.TileLayer(id='map_style_tileLayer'), dl.LayerGroup(id="layer"),
dl.GeoJSON(
data=dev_borders, # Use the loaded GeoJSON data
id="dev_layer",
style={"weight": 2, "dashArray": "3", "fillOpacity": 0.3},
# Default style for the paths
hoverStyle={"weight": 5, "color": "orange", "dashArray": ""} # Style for hovered countries
),
dl.LocateControl(
locateOptions={'enableHighAccuracy': True, 'drawMarker': True, 'flyTo': True, 'showCompass': True}),
dl.EasyButton(icon="fa-globe", title="Map Switch", id="site_management_satellite_button")
]
new_center=[38.75593, -3.93264]
layout = [dl.Map(center=new_center, zoom=2, children=map_context,
id='map',
style={'width': '100vw', 'height': '100vh'})]
@dash.callback(Output("layer", "children"), [Input("map", "clickData")], prevent_initial_call=True)
def map_click(click_lat_lng):
if click_lat_lng is not None:
coordinates = click_lat_lng['latlng']
lat, lon = coordinates.values()
if point_in:
# Return a list of new elements to add to the 'layer' component
return dl.Marker(
position=[lat, lon],
children=dl.Tooltip("Chosen 🗺 Location: ({:.5f}, {:.5f})".format(lat, lon)),
icon={'iconUrl': 'assets/site_icon.png',
'iconRetinaUrl': 'assets/site_icon.png',
'iconSize': [40, 40], 'iconAnchor': [12, 12], 'popupAnchor': [0, -12],
'shadowUrl': None, 'shadowSize': None, 'shadowAnchor': None}
)
return dash.no_update
Needs a little adjusting but its a solid outline to help you understand how to go about setting this up within your own project.
hope this helps.