<!DOCTYPE html>
<html>
<head>
<link data-require="leaflet@0.7.7" data-semver="0.7.7" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.0/leaflet.css" />
<script data-require="leaflet@0.7.7" data-semver="0.7.7" src="//cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.0/leaflet.js"></script>
<script src="https://npmcdn.com/leaflet-geometryutil"></script>
</head>
<body>
<h1>Demo for 'closest' methods</h1>
<p>
To test, just click on the map to see the closest segment.<br>
The <strong>closests point</strong> from polygon1, polyline1 and polyline2 will be displayed with a blue marker.<br>
The <strong>closest layer</strong> will be switched in green and written after the method.<br>
The <strong>closest layer by snap</strong> will just be written after the method.<br>
The <strong>closest point on segment</strong> will be calculated with the red segment, and displayed as a marker on it.
</p>
<div id="map" style="height: 300px"></div>
<pre>
<code>closest(map, layer, latlng, vertices)</code>
vertices parameter <input type="checkbox" id="p_vertices">
</pre>
<pre>
<code style="color:green">closestLayer(map, layers, latlng) : <span id='closestLayer'></span> </code>
</pre>
<pre>
<code>closestLayerSnap(map, layers, latlng, tolerance, withVertices) : <span id='closestLayerSnap'></span> </code>
tolerance parameter (default Infinity if empty) <input type="number" id="p_tolerance">
withVertices parameter <input type="checkbox" id="p_withVertices" checked>
</pre>
<pre>
<code style="color:red">closestOnSegment(map, latlng, latlngA, latlngB)</code>
<code id="closestOnSegment"></code>
</pre>
<script src="geojson.js"></script>
<script src="script.js"></script>
</body>
</html>
var llPolyline1 = [ [39.76116, -105.03702],
[39.76684, -105.01608],
[39.76116, -104.95874]],
llPolyline2 = [ [39.7572, -105.04217],
[39.74783, -105.04698],
[39.7308, -105.0432],
],
llSegment = [ [39.73397, -105.03256],
[39.73397, -104.93681]
],
llPolygon1 = [
[[39.75324, -104.97934],
[39.75879, -104.96681],
[39.75379, -104.94681],
[39.74379, -104.93681],
[39.74348, -104.97711] ], // outer ring
[ [39.75245, -104.97471],
[39.7547, -104.9663],
[39.75206, -104.95171],
[39.74849, -104.94965],
[39.74744, -104.97385] ] // hole
],
_map = L.map('map').setView(/*[51.505, -0.09]*/ [39.74739, -105], 13),
polygon1 = L.polygon(llPolygon1, {color: 'blue', className: 'polygon1'}).addTo(_map),
polyline1 = L.polyline(llPolyline1, {color: 'blue', className: 'polyline1'}).addTo(_map),
polyline2 = L.polyline(llPolyline2, {color: 'blue', className: 'polyline2'}).addTo(_map),
segment = L.polyline(llSegment, {color: 'red', className: 'segment'}).addTo(_map),
marker = null,
markerClosestPolygon1 = null,
markerClosestPolyline1 = null,
markerClosestPolyline2 = null,
markerClosestSegment = null;
var bicycle = L.geoJson([bicycleRental, campus], {
style: function (feature) {
return feature.properties && feature.properties.style;
},
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, {
radius: 8,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
});
}
}).addTo(_map),
freebusLayer = L.geoJson(freeBus, {
filter: function (feature, layer) {
if (feature.properties) {
// If the property "underConstruction" exists and is true, return false (don't render features under construction)
return feature.properties.underConstruction !== undefined ? !feature.properties.underConstruction : true;
}
return false;
}
}).addTo(_map),
coorsLayer = L.geoJson(coorsField, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {className: 'marker'});
}
}).addTo(_map);
// console.log("latlngs of polygon1")
// console.log(polygon1.getLatLngs())
// console.log("latlngs of polyline1")
// console.log(polyline1.getLatLngs())
// console.log("latlngs of polyline2")
// console.log(polyline2.getLatLngs())
function init() {
if (marker) _map.removeLayer(marker);
if (markerClosestPolygon1) _map.removeLayer(markerClosestPolygon1);
if (markerClosestPolyline1) _map.removeLayer(markerClosestPolyline1);
if (markerClosestPolyline2) _map.removeLayer(markerClosestPolyline2);
if (markerClosestSegment) _map.removeLayer(markerClosestSegment);
polygon1.setStyle({color:'blue'});
polyline1.setStyle({color:'blue'});
polyline2.setStyle({color:'blue'});
document.getElementById('closestLayer').innerHTML = '';
document.getElementById('closestLayerSnap').innerHTML = '';
}
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}).addTo(_map);
_map.on('click', function(e) {
init();
marker = L.marker(e.latlng).addTo(_map).bindPopup(e.latlng + '<br/>' + e.layerPoint).openPopup();
var p_vertices = document.getElementById('p_vertices').checked,
p_tolerance = document.getElementById('p_tolerance').value !== '' ? parseInt(document.getElementById('p_tolerance').value) : Infinity,
p_withVertices = document.getElementById('p_withVertices').checked,
closestPointToPolygon1 = L.GeometryUtil.closest(_map, polygon1, e.latlng, p_vertices),
closestPointToPolyline1 = L.GeometryUtil.closest(_map, polyline1, e.latlng, p_vertices),
closestPointToPolyline2 = L.GeometryUtil.closest(_map, polyline2, e.latlng, p_vertices),
closestLayer = L.GeometryUtil.closestLayer(_map, bicycle.getLayers().concat(coorsLayer.getLayers(), polyline1, polyline2, polygon1), e.latlng),
closestLayerSnap = L.GeometryUtil.closestLayerSnap(_map, [ polyline1, polygon1, polyline2 ], e.latlng, p_tolerance, p_withVertices),
closestOnSegment = L.GeometryUtil.closestOnSegment(_map, e.latlng, llSegment[0], llSegment[1]);
// display the closest points
markerClosestPolygon1 = L.marker(closestPointToPolygon1).addTo(_map).bindPopup('Closest point on polygon1');
markerClosestPolyline1 = L.marker(closestPointToPolyline1).addTo(_map).bindPopup('Closest point on polyline1');
markerClosestPolyline2 = L.marker(closestPointToPolyline2).addTo(_map).bindPopup('Closest point on polyline2');
// change the color of closest layer
if (typeof closestLayer.layer.setStyle === 'function') {
closestLayer.layer.setStyle({'color':'green'});
}
document.getElementById('closestLayer').innerHTML = closestLayer.layer.options.className;
// display the closest position for snap
document.getElementById('closestLayerSnap').innerHTML = closestLayerSnap ? closestLayerSnap.layer.options.className : 'unknown';
// display the closest point on red segment
markerClosestSegment = L.marker(closestOnSegment).addTo(_map).bindPopup('Closest point on segment');
})
Demo to test closest, closestLayer, closestLayerSnap and closestOnSegment methods of Leaflet.GeometryUtil plugin.
// data from leaflet documentation
// http://leafletjs.com/examples/geojson-example.html
var freeBus = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.00341892242432, 39.75383843460583],
[-105.0008225440979, 39.751891803969535]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": false
},
"id": 1
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-105.0008225440979, 39.751891803969535],
[-104.99820470809937, 39.74979664004068]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": true
},
"id": 2
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[-104.99820470809937, 39.74979664004068],
[-104.98689651489258, 39.741052354709055]
]
},
"properties": {
"popupContent": "This is free bus that will take you across downtown.",
"underConstruction": false
},
"id": 3
}
]
};
var lightRailStop = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"popupContent": "18th & California Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98999178409576, 39.74683938093904]
}
},{
"type": "Feature",
"properties": {
"popupContent": "20th & Welton Light Rail Stop"
},
"geometry": {
"type": "Point",
"coordinates": [-104.98689115047453, 39.747924136466565]
}
}
]
};
var bicycleRental = {
"type": "FeatureCollection",
"features": [
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9998241,
39.7471494
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 51
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9983545,
39.7502833
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 52
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9963919,
39.7444271
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 54
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9960754,
39.7498956
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 55
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9933717,
39.7477264
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 57
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9913392,
39.7432392
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 58
},
{
"geometry": {
"type": "Point",
"coordinates": [
-104.9788452,
39.6933755
]
},
"type": "Feature",
"properties": {
"popupContent": "This is a B-Cycle Station. Come pick up a bike and pay by the hour. What a deal!"
},
"id": 74
}
]
};
var campus = {
"type": "Feature",
"properties": {
"popupContent": "This is the Auraria West Campus",
"style": {
weight: 2,
color: "#999",
opacity: 1,
fillColor: "#B0DE5C",
fillOpacity: 0.8
}
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-105.00432014465332, 39.74732195489861],
[-105.00715255737305, 39.74620006835170],
[-105.00921249389647, 39.74468219277038],
[-105.01067161560059, 39.74362625960105],
[-105.01195907592773, 39.74290029616054],
[-105.00989913940431, 39.74078835902781],
[-105.00758171081543, 39.74059036160317],
[-105.00346183776855, 39.74059036160317],
[-105.00097274780272, 39.74059036160317],
[-105.00062942504881, 39.74072235994946],
[-105.00020027160645, 39.74191033368865],
[-105.00071525573731, 39.74276830198601],
[-105.00097274780272, 39.74369225589818],
[-105.00097274780272, 39.74461619742136],
[-105.00123023986816, 39.74534214278395],
[-105.00183105468751, 39.74613407445653],
[-105.00432014465332, 39.74732195489861]
],[
[-105.00361204147337, 39.74354376414072],
[-105.00301122665405, 39.74278480127163],
[-105.00221729278564, 39.74316428375108],
[-105.00283956527711, 39.74390674342741],
[-105.00361204147337, 39.74354376414072]
]
],[
[
[-105.00942707061768, 39.73989736613708],
[-105.00942707061768, 39.73910536278566],
[-105.00685214996338, 39.73923736397631],
[-105.00384807586671, 39.73910536278566],
[-105.00174522399902, 39.73903936209552],
[-105.00041484832764, 39.73910536278566],
[-105.00041484832764, 39.73979836621592],
[-105.00535011291504, 39.73986436617916],
[-105.00942707061768, 39.73989736613708]
]
]
]
}
};
var coorsField = {
"type": "Feature",
"properties": {
"popupContent": "Coors Field"
},
"geometry": {
"type": "Point",
"coordinates": [-104.99404191970824, 39.756213909328125]
}
};