Большую часть того, что вы хотите, довольно легко сделать с помощью служебных методов Leaflet. Если вы хотите сделать это со сложной формой, например L.Polygon
, вам понадобится что-то вроде TurfJS
Для L.Circle
вам нужно вычислить расстояние между центром круга и сравнить его с радиусом:
var marker = new L.Marker(...),
circle = new L.Circle(...);
var contains = circle.getLatLng().distanceTo(marker.getLatLng()) < circle.getRadius();
Для L.Rectangle
вам нужно получить его граничный объект и использовать метод contains:
var marker = new L.Marker(...),
rectangle = new L.Rectangle(...);
var contains = rectangle.getBounds().contains(marker.getLatLng());
Как сказано для сложных полигонов, я использую Turf, но есть и другие библиотеки и плагины. Вот пример использования метода Турфа inside
. В качестве параметров требуется точка и полигон GeoJSON, поэтому обратите внимание на преобразование:
var marker = new L.Marker(...),
polygon = new L.Polygon(...);
var contains = turf.inside(marker.toGeoJSON(), polygon.toGeoJSON());
Вы можете обернуть их в удобные методы для каждого соответствующего класса:
L.Polygon.include({
contains: function (latLng) {
return turf.inside(new L.Marker(latLng).toGeoJSON(), this.toGeoJSON());
}
});
L.Rectangle.include({
contains: function (latLng) {
return this.getBounds().contains(latLng);
}
});
L.Circle.include({
contains: function (latLng) {
return this.getLatLng().distanceTo(latLng) < this.getRadius();
}
});
var marker = new L.Marker(...),
polygon = new L.Polygon(...),
rectangle = new L.Rectangle(...),
circle = new L.Circle(...);
polygon.contains(marker.getLatLng());
rectangle.contains(marker.getLatLng());
circle.contains(marker.getLatLng());
Обратите внимание, что если вы реализуете метод многоугольника, метод прямоугольника не нужен. Поскольку прямоугольник является продолжением многоугольника, он унаследует метод. Я оставил это там, чтобы закончить.
Теперь легко перебирать маркеры и сравнивать их:
map.on(L.Draw.Event.CREATED, function (e) {
markers.eachLayer(function (marker) {
if (!e.layer.contains(marker.getLatLng())) {
marker.remove();
}
});
});
Надеюсь, что это поможет, вот рабочий фрагмент:
var map = new L.Map('leaflet', {
'center': [0, 0],
'zoom': 0
});
var markers = new L.LayerGroup().addTo(map);
for (var i = 0; i < 300; i++) {
var marker = new L.Marker([
(Math.random() * (90 - -90) + -90).toFixed(5) * 1,
(Math.random() * (180 - -180) + -180).toFixed(5) * 1
]).addTo(markers);
}
new L.Control.Draw({
draw: {
marker : false,
polygon : true,
polyline : false,
rectangle: true,
circle : {
metric: 'metric'
}
},
edit: false
}).addTo(map);
L.Polygon.include({
contains: function (latLng) {
return turf.inside(new L.Marker(latLng).toGeoJSON(), this.toGeoJSON());
}
});
L.Rectangle.include({
contains: function (latLng) {
return this.getBounds().contains(latLng);
}
});
L.Circle.include({
contains: function (latLng) {
return this.getLatLng().distanceTo(latLng) < this.getRadius();
}
});
map.on(L.Draw.Event.CREATED, function (e) {
markers.eachLayer(function (marker) {
if (!e.layer.contains(marker.getLatLng())) {
marker.remove();
}
});
});
body {
margin: 0;
}
html, body, #leaflet {
height: 100%;
}
<!DOCTYPE html>
<html>
<head>
<title>Leaflet 1.0.3</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/[email protected]/dist/leaflet.css" />
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.9/leaflet.draw.css" />
</head>
<body>
<div id="leaflet"></div>
<script type="application/javascript" src="//unpkg.com/[email protected]/dist/leaflet.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.9/leaflet.draw.js"></script>
<script type="application/javascript" src="//unpkg.com/@turf/turf@latest/turf.min.js"></script>
</body>
</html>
person
iH8
schedule
30.05.2017