ipyleaflet icon indicating copy to clipboard operation
ipyleaflet copied to clipboard

Display GeoJSON layer popup at mouse clicked location

Open giswqs opened this issue 1 year ago • 0 comments

Is it possible to display popups for a GeoJSON layer at mouse clicked locations? It seems the event handler does not contain mouse clicked coordinates. One workaround is to use the polygon/polyline centroid, which is not ideal for a large feature where the popup shows up very far away from the mouse clicked location.

Reference issue: https://github.com/opengeos/leafmap/issues/873

from ipyleaflet import Map, GeoJSON, Popup
import json
from shapely.geometry import shape
import ipywidgets as widgets

# Create a map centered at a specific location
m = Map(center=(51.55, -0.09), zoom=10)

# Example GeoJSON data with two polygons
geojson_data = {
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "name": "Polygon A",
                "popup_content": "This is Polygon A."
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-0.1, 51.5],
                    [-0.1, 51.6],
                    [-0.05, 51.6],
                    [-0.05, 51.5],
                    [-0.1, 51.5]
                ]]
            }
        },
        {
            "type": "Feature",
            "properties": {
                "name": "Polygon B",
                "popup_content": "This is Polygon B."
            },
            "geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-0.08, 51.48],
                    [-0.08, 51.52],
                    [-0.03, 51.52],
                    [-0.03, 51.48],
                    [-0.08, 51.48]
                ]]
            }
        }
    ]
}

# Create a GeoJSON layer
geojson_layer = GeoJSON(data=geojson_data)

output = widgets.Output()

# Function to calculate the centroid of a polygon
def calculate_centroid(polygon_coordinates):
    polygon = shape({
        "type": "Polygon",
        "coordinates": polygon_coordinates
    })
    centroid = polygon.centroid
    return centroid.y, centroid.x  # Return as (lat, lon)

# Define a function to handle the on-click event
def on_click_handler(event, feature, **kwargs):
    # Calculate the centroid of the polygon
    centroid = calculate_centroid(feature['geometry']['coordinates'])
    with output:
        print(f"event: {event}")
        print(f"kwargs: {kwargs}")
        print(f"centroid: {centroid}")
        print(f"properties: {feature['properties']['popup_content']}")
     
    # Create a popup with the content from GeoJSON properties
    popup = Popup(
        location=centroid,
        child=widgets.HTML(feature['properties']['popup_content']),
        close_button=False,
        auto_close=True
    )
    
    # Add the popup to the map
    m.add_layer(popup)

# Bind the click event to the GeoJSON layer
geojson_layer.on_click(on_click_handler)

# Add the GeoJSON layer to the map
m.add_layer(geojson_layer)

# Display the map
m

image

giswqs avatar Aug 21 '24 14:08 giswqs