Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GeoJsonDataLayer: support for PointToLayer methods that customize the markers #38

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions BlazorLeaflet/BlazorLeaflet.Samples/Pages/GeoJson.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
@page "/geojson"

@using BlazorLeaflet.Models
@using BlazorLeaflet.Models.Events
@inject IJSRuntime jsRuntime

<h1>Blazor Leaflet</h1>

<p>
This page demos GeoJSON layers.
</p>

<p>
By default, each point in a GeoJSON layer is just a normal marker. Instead,
you can optionally set <code>PointToLayer</code> to a method that
customizes the layer each point corresponds to. Currently, only markers are
supported.
</p>

<div style="height: 500px; width: 500px;">
<LeafletMap Map="_map" />
</div>

@code
{
private Map _map;
private LatLng _markerLatLng = new LatLng { Lat = 18, Lng = -76 };

protected override void OnInitialized()
{
var badEuropeMap = @"
{
""type"": ""FeatureCollection"",
""features"": [
{
""type"": ""Feature"",
""properties"": {
""country"": ""Cuba""
},
""geometry"": {
""type"": ""Point"",
""coordinates"": [
-82.44140625,
22.917922936146045
]
}
},
{
""type"": ""Feature"",
""properties"": {
""country"": ""USA""
},
""geometry"": {
""type"": ""Point"",
""coordinates"": [
-80.244140625,
25.720735134412106
]
}
},
{
""type"": ""Feature"",
""properties"": {
""country"": ""Venezuela""
},
""geometry"": {
""type"": ""Point"",
""coordinates"": [
-68.9501953125,
12.211180191503997
]
}
}
]
}
";

var dataLayer = new GeoJsonDataLayer
{
GeoJsonData = badEuropeMap
};

dataLayer.PointToLayer = new Func<GeoJsonFeature, LatLng, Marker>((feature, latLng) =>
{
return new Marker(latLng)
{
Icon = new Icon
{
Size = new System.Drawing.Size(24, 24),
Url = "https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Run.svg/200px-Run.svg.png",
ClassName = "map-icon",
},
Tooltip = new Tooltip
{
Content = "This is a tooltip",
},
Popup = new Popup
{
Content = "This is a popup",
},
Title = "This is the title attribute"
};
});

_map = new Map(jsRuntime)
{
Center = _markerLatLng,
Zoom = 4.8f
};

_map.OnInitialized += () =>
{
_map.AddLayer(new TileLayer
{
UrlTemplate = "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
Attribution = "&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
});

_map.AddLayer(dataLayer);
};
}
}
9 changes: 6 additions & 3 deletions BlazorLeaflet/BlazorLeaflet.Samples/Shared/NavMenu.razor
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,15 @@
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
<NavLink class="nav-link" href="shapes" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Shapes
</NavLink>
<NavLink class="nav-link" href="customcontrols" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Custom Controls
</NavLink>
<NavLink class="nav-link" href="geojson" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> GeoJSON Data
</NavLink>
<NavLink class="nav-link" href="shapes" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Shapes
</NavLink>
</li>
</ul>
</div>
Expand Down
25 changes: 24 additions & 1 deletion BlazorLeaflet/BlazorLeaflet/Models/GeoJsonDataLayer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Text;

Expand All @@ -7,5 +8,27 @@ namespace BlazorLeaflet.Models
public class GeoJsonDataLayer : InteractiveLayer
{
public string GeoJsonData { get; set; }

public bool HasPointToLayerFunc => PointToLayer != null;

[System.Text.Json.Serialization.JsonIgnore]
public Func<GeoJsonFeature, LatLng, Marker> PointToLayer { get; set; }

[JSInvokable]
public object CallPointToLayer(GeoJsonFeature feature, LatLng latLng)
{
var layer = PointToLayer(feature, latLng);

if (!(layer is Marker))
throw new NotSupportedException("Only Marker layers are currently implemented for PointToLayer.");

return new { Layer = layer, Ref = DotNetObjectReference.Create(layer) };
}
}

public class GeoJsonFeature
{
public object Geometry { get; set; }
public Dictionary<string, object> Properties { get; set; }
}
}
44 changes: 44 additions & 0 deletions BlazorLeaflet/BlazorLeaflet/wwwroot/leafletBlazorInterops.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,50 @@ window.leafletBlazor = {
}
};

if (geodata.hasPointToLayerFunc) {
options.pointToLayer = function pointToLayer(geoJsonPoint, latlng) {
var _mapId = mapId;

// we need to first pass leaflet an empty layer group,
// then asynchronously add our actual layer to it

var emptyGroup = L.layerGroup();

objectReference.invokeMethodAsync("CallPointToLayer", geoJsonPoint, latlng)
.then(function (result) {
const marker = result.layer;

var options = {
...createInteractiveLayer(marker),
keyboard: marker.isKeyboardAccessible,
title: marker.title,
alt: marker.alt,
zIndexOffset: marker.zIndexOffset,
opacity: marker.opacity,
riseOnHover: marker.riseOnHover,
riseOffset: marker.riseOffset,
pane: marker.pane,
bubblingMouseEvents: marker.isBubblingMouseEvents,
draggable: marker.draggable,
autoPan: marker.useAutopan,
autoPanPadding: marker.autoPanPadding,
autoPanSpeed: marker.autoPanSpeed
};

if (marker.icon !== null) {
options.icon = createIcon(marker.icon);
}
const mkr = L.marker(marker.position, options);
connectMarkerEvents(mkr, objectReference);
setTooltipAndPopupIfDefined(marker, mkr);

mkr.addTo(emptyGroup);
});

return emptyGroup;
};
}

const geoJsonLayer = L.geoJson(geoDataObject, options);
addLayer(mapId, geoJsonLayer, geodata.id);
},
Expand Down