Как узнать, содержится ли точка Lat, Lng в круге?

Хорошо, очень понятно. Я использую карты Google, и я пытаюсь выяснить, находится ли точка lat, длинная точка в круге радиуса, например x (x выбирается пользователем).

Ограничивающий блок не будет работать для этого. Я уже пробовал использовать следующий код:

distlatLng = new google.maps.LatLng(dist.latlng[0],dist.latlng[1]);
var latLngBounds = circle.getBounds();
if(latLngBounds.contains(distlatLng)){
 dropPins(distlatLng,dist.f_addr);
}

Это все еще приводит к тому, что маркеры располагаются за пределами круга.

Я предполагаю, что это простые математические вычисления, требующие вычисления кривизны или области, но я не уверен, с чего начать. Любые предложения?

6 ответов

Я был немного глуп. Думая об этом, мы можем использовать теорему Пифагора.

Мы имеем максимальное расстояние от точки (X миль) и двух широт и двух долгот. Если мы построим треугольник, используя их, то мы можем решить для расстояния от точки.

Итак, мы знаем, что point1 с координатами lat1,lng1 является центром круга, а point2 с координатами lat2,lng2 - это точка, которую мы пытаемся решить, находится в круге или нет.

Мы формируем прямоугольный треугольник, используя точку, определяемую point1 и point2. Это, point3 будет иметь координаты lat1,lng2 или lat2,lng1 (неважно, какой). Затем мы вычисляем разности (или, если хотите) расстояния - latDiff = lat2-lat1 и lngDiff = lng2-lng1

затем вычисляем расстояние от центра с помощью Pythagorus - dist=sqrt(lngDiff^2+latDiff^2).

Мы должны перевести все в метры так, чтобы он корректно работал с картами Google, поэтому мили умножаются на 1609 (приблизительное) и градусы широты/долготы на 111000 (приблизительное). Это не совсем точно, но он выполняет адекватную работу.

Надеюсь, что все имеет смысл.


Рабочее решение с табуляционным центральным маркером

Вы когда-нибудь пробовали contains? Взгляните на конструктор LatLngBounds.

Я написал статью об этом, которая содержит ссылку на рабочий пример JSFiddle.net.

Обновленная версия.


К сожалению, Пифагор не помогает в сфере. Таким образом, ответ Стюарта Борода неверен; долготы не имеют фиксированного отношения к метрам, но зависят от широты.

Правильный способ - использовать формулу для больших расстояний круга. Хорошим приближением, считая сферическую землю, является это (в С++):

/** Find the great-circle distance in metres, assuming a spherical earth, between two lat-long points in degrees. */
inline ****** GreatCircleDistanceInMeters(****** aLong1,****** aLat1,****** aLong2,****** aLat2)
 {
 aLong1 *= ***********************;
 aLat1 *= ***********************;
 aLong2 *= ***********************;
 aLat2 *= ***********************;
 ****** cos_angle = sin(aLat1) * sin(aLat2) + cos(aLat1) * cos(aLat2) * cos(aLong2 - aLong1);
 /*
 Inaccurate trig functions can cause cos_angle to be a tiny amount
 greater than 1 if the two positions are very close. That in turn causes
 acos to give a domain error and return the special floating point value
 -1.#IND000000000000, meaning 'indefinite'. Observed on VS2008 on 64-bit Windows.
 */
 if (cos_angle >= 1)
 return 0;
 ****** angle = acos(cos_angle);
 return angle * KEquatorialRadiusInMetres;
 }

где

const ****** ********* = 3.141592654;
const ****** *********************** = ********* / 180.0;

и

/**
A constant to convert radians to metres for the Mercator and other projections.
It is the semi-major axis (equatorial radius) used by the WGS 84 datum (see http://en.wikipedia.org/wiki/WGS84).
*/
const int32 KEquatorialRadiusInMetres = 6378137;


Это очень просто. Вам просто нужно рассчитать расстояние между центром и заданной точкой и сравнить его с радиусом. Вы можете получить помощь для вычисления расстояния между двумя латами из здесь


Используйте геометрию Google Maps API для вычисления расстояния между центром круга и маркером, а затем сравните его с вашим радиусом.

var pointIsInsideCircle = google.maps.geometry.spherical.computeDistanceBetween(circle.getCenter(), point) <= circle.getRadius();


Следующий код работает для меня: мой маркер нельзя вытащить за пределы круга, вместо этого он просто висит на своем краю (в любом направлении), и сохраняется последняя действительная позиция.

Эта функция является обработчиком событий для события перетаскивания маркеров.

_markerDragged : function() {
 var latLng = this.marker.getPosition();
 var center = this.circle.getCenter();
 var radius = this.circle.getRadius();
 if (this.circleBounds.contains(latLng) &&
 (google.maps.geometry.spherical.computeDistanceBetween(latLng, center) <= radius)) {
 this.lastMarkerPos = latLng;
 this._geocodePosition(latLng);
 } else {
 // Prevent dragging marker outside circle
 // see (comments of) http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/
 // see http://www.mvjantzen.com/blog/?p=3190 and source code of http://mvjantzen.com/cabi/trips4q2012.html
 this.marker.setPosition(this.lastMarkerPos);
 }
},

Благодаря http://unserkaiser.com/code/google-maps-marker-check-if-in-circle/ и http://www.mvjantzen.com/blog/?p=3190.

licensed under cc by-sa 3.0 with attribution.