Skip to content

Instantly share code, notes, and snippets.

  • Save kofronpi/9f61ff50ea773a00d4f2 to your computer and use it in GitHub Desktop.
Save kofronpi/9f61ff50ea773a00d4f2 to your computer and use it in GitHub Desktop.
Example of one way to integrate Leafletjs w/ Leaflet.draw extending it to add methods to: - Load markers from KML and overlay onto map. - Return array of all markers on a map. - Return array of all polygons on a map. - Return array of markers which are within a specified polygon. Requires UnderscoreJS and @shramov/leaflet-plugins (for KML loader…
// <summary>
// Logging methods.
// </summary>
Log = {
Dump: function (object)
{
if (object)
{
console.debug(object);
}
},
Info: function (message, object)
{
console.info("### " + message)
this.Dump(object);
},
Error: function (message, object)
{
console.error("+++ " + message);
this.Dump(object);
},
}
// <summary>
// Return array of polygons, for each polygon
// return the lat/longs which define the shape
// of the object.
// </sumary>
// <returns>
// [
// Array[3]
// 0: n.LatLng
// 1: n.LatLng
// 2: n.LatLng
// length: 3
// __proto__: Array[0]
// ,
// Array[3],
// Array[3]
// ]
// </returns>
function GetPolygons()
{
var items = window.drawnItems._layers;
var collection = _.map(items, function(polygon)
{ return polygon._latlngs;
});
return collection;
}
// <summary>
// Returns array of all markers (lat/long/description)
// any markers found with invalid data are ignored.
// </sumary>
function GetMarkers()
{
var items = window.markers._map._layers;
var collection = _.map(items, function(marker)
{
var description;
var location;
if (_.isEmpty(marker._popup))
{
Log.Info("marker found without description", marker);
return;
}
description = marker._popup._content;
if (_.isEmpty(marker._latlng))
{
Log.Info("marker found without latitude/longitude", marker);
return;
}
location = marker._latlng;
return {
description: description,
location: location
};
});
var results = _.filter(collection, function(marker)
{
// exclude any markers that have empty/undefined
// description or locations from the results
if (_.isEmpty(marker)) return false;
if (_.isEmpty(marker.description)) return false;
if (_.isEmpty(marker.location)) return false;
// marker has passed validation, allow it to exist.
return true;
});
return results;
}
// <summary>
// Checks if marker is within a polygon, algorithm
// originally programmed in C, have ported it to JS.
// disclaimer: no idea how or even why this algorithm
// works. See the original implementation for a fantastic
// explanation (with pictures) of the problem space/theory.
// http://alienryderflex.com/polygon/
// </summary>
function IsMarkerInPolygon(marker, polygon)
{
if (_.isEmpty(polygon))
{
Log.Error("IsMarkerInPolygon: invalid polygon", polygon);
return false;
}
if (_.isEmpty(marker))
{
Log.Error("IsMarkerInPolygon: invalid marker", marker);
return false;
}
var j = 0;
var sides = polygon.length;
var x = marker.lng;
var y = marker.lat;
var inPoly = false;
for (var i=0; i < sides; i++) {
j++;
if (j == sides) {j = 0;}
if (((polygon[i].lat < y) && (polygon[j].lat >= y)) || ((polygon[j].lat < y) && (polygon[i].lat >= y)))
{
if (polygon[i].lng + (y - polygon[i].lat) / (polygon[j].lat-polygon[i].lat) * (polygon[j].lng - polygon[i].lng)<x )
{
inPoly = !inPoly
}
}
}
return inPoly;
}
// <summary>
// Returns all markers found within a polygon.
// </summary>
function GetMarkersInPolygon(polygon)
{
if (_.isEmpty(polygon))
{
Log.Error("GetMarkersInPolygon: invalid polygon", polygon);
return;
}
var markers = GetMarkers();
var results = _.filter(markers, function(marker)
{
return IsMarkerInPolygon(marker.location, polygon);
});
return results;
}
var map = L.map('map');
window.drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
draw: {
position: 'topleft',
polygon: {
title: 'Draw a polygon',
allowIntersection: false,
drawError: {
color: 'red',
timeout: 1000
},
shapeOptions: {
color: '#333333'
}
},
circle: false,
polyline: false,
marker: false,
rectangle: false
},
edit: {
featureGroup: drawnItems,
edit: {
title: 'Edit a polygon'
},
remove: {
title: 'Delete a polygon'
}
}
});
map.addControl(drawControl);
window.markers = new L.KML("markers.kml", {async: true});
markers.on("loaded", function(e) {
map.addLayer(markers);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment