Я хотел бы обнаружить, что a google.maps.LatLng
находится внутри google.maps.Polygon
.
Как я могу это сделать?
Приветствия,
Я хотел бы обнаружить, что a google.maps.LatLng
находится внутри google.maps.Polygon
.
Как я могу это сделать?
Приветствия,
Другое решение: Google-Maps-Point-in-Polygon
Расширение Javascript Google Maps v3 для класса Polygon для определения того, находится ли в нем точка...
Вы можете использовать это в карте Google V3: -
google.maps.geometry.poly.containsLocation(google.maps.LatLng(latitude, longitude),polygons);
Полигоны - это объект, возвращаемый функцией после polygoncomplete.
var polygons=null;
google.maps.event.addDomListener(drawingManager, "polygoncomplete", function(polygon) {
polygons=polygon;
});
ссылка https://developers.google.com/maps/documentation/javascript/reference
Google предоставляет собственную реализацию в библиотеке геометрии, которую я еще не проверил, но, по-видимому, охватывает случаи кросс, обсуждаемые в других ответах.
См. метод containsplace описанный здесь. Обратите внимание, что вам нужно явно импортировать библиотеку геометрии, поскольку она не находится в API базовой карты
Я использовал этот алгоритм для обнаружения того, что точка находится внутри многоугольника: http://alienryderflex.com/polygon/
Я добавил новый метод contains
в Polygon:
// Add a function contains(point) to the Google Maps API v.3
google.maps.Polygon.prototype.contains = function(point) {
var j=0;
var oddNodes = false;
var x = point.lng();
var y = point.lat();
var paths = this.getPath();
for (var i=0; i < paths.getLength(); i++) {
j++;
if (j == paths.getLength()) {j = 0;}
if (((paths.getAt(i).lat() < y) && (paths.getAt(j).lat() >= y))
|| ((paths.getAt(j).lat() < y) && (paths.getAt(i).lat() >= y))) {
if ( paths.getAt(i).lng() + (y - paths.getAt(i).lat())
/ (paths.getAt(j).lat()-paths.getAt(i).lat())
* (paths.getAt(j).lng() - paths.getAt(i).lng())<x ) {
oddNodes = !oddNodes
}
}
}
return oddNodes;
}
google.maps.Polyline.prototype.contains = google.maps.Polygon.prototype.contains;
Каждый описанный здесь метод терпит неудачу так или иначе.
Методы, заданные Андреем я и Natim , не рассматривают многоугольники с геодезическими ребрами. Эти методы также не понимают, что негеодезический край в Картах Google находится прямо в проекции Меркатора. Эти методы предполагают, что вершины лежат на сетке равных расстояний lat/lon, где одна градусная широта равна одной градусу долготы. В результате этой ошибки эти методы укажут, что точка находится за пределами многоугольника, в то время как для некоторых случаев отображается внутри. Это легко наблюдать для длинных не вертикальных/не горизонтальных кромок. Чтобы решить эту проблему, все точки сначала должны быть преобразованы из координат широты, долготы в X, Y в проекции Меркатора. Вот метод преобразования координат из lat/lon в x/y в Mercator. (Недостает точности) В качестве основы для альтернативного метода можно использовать навигационную линию Rhumb. Экспериментальная версия Google Maps 3.10 реализует этот метод.
Метод, упомянутый Paul Gibbs, swapnil udare и Adi Lester , рассматривает геодезические ребра, но с Google Maps v3.9 он использует тот же самый метод, упомянутый выше для негеодезических многоугольников. Таким образом, он также страдает от той же проблемы, описанной выше.
Обновление - Проблема с Картами Google была исправлена в текущей экспериментальной версии Google Maps v3.10.
Нет необходимости в сложных алгоритмах, я смог достичь этого, используя метод isPointInPath() html canvas.
http://www.w3schools.com/tags/canvas_ispointinpath.asp
Создайте элемент холста. Нарисуйте многоугольник с несколькими конечными точками, используя методы moveTo(), lineTo(). Проверьте, находится ли точка (x, y) внутри многоугольника с использованием метода isPointInPath().
<canvas id="canvas"></canvas>
//x,y are coordinate of the point that needs to be tested
//coordinates contains all endpoint of a polygon in format of x1,y1,x2,y2,x3,y3....
function isPointInPolygon(x, y, coordinates) {
var ctx = canvas.getContext("2d");
var coords = coordinates.split(',');
if (coords != null && coords.length > 4) {
ctx.beginPath();
ctx.moveTo(coords[0], coords[1]);
for (j = 2; j < coords.length; j++) {
ctx.lineTo(coords[j], coords[j + 1]);
j++;
}
ctx.closePath();
if (ctx.isPointInPath(x, y))
return true;
else
return false;
}
return false;
}