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

Хорошо, довольно понятно. Я использую карты Google и пытаюсь выяснить, находится ли широкая и длинная точка в пределах круга радиуса, скажем, 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);
}

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

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


person Stuart Beard    schedule 16.12.2010    source источник
comment
Этот пост SO может дать вам представление тебе нужно.   -  person npinti    schedule 16.12.2010


Ответы (6)


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

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

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

Скриншот jsFiddle


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

person kaiser    schedule 16.12.2011
comment
@zavidovych Это известная ошибка. Он исчез на какое-то время и вернулся с версией 3.9, я думаю. Я подал отчет об ошибке. Есть еще один способ, который я опубликую, когда у меня будет время. - person kaiser; 16.06.2014
comment
Хорошее решение. Не было в наличии, когда он мне был нужен :) - person Stuart Beard; 15.08.2014
comment
Хорошее решение. Содержит, кажется, работает на данный момент. - person One-One; 17.04.2015
comment
измененная версия этого примера на demo.developerextensions.com/ ответы/, которые также проверяют расстояние с помощью пользовательской функции, которую можно использовать без библиотеки Google. - person surinder singh; 10.02.2016
comment
@surindersingh, это великолепно! Спасибо! Возможно, вы захотите добавить это к ответу (пожалуйста, отправьте edit). - person kaiser; 10.02.2016

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

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

/** Find the great-circle distance in metres, assuming a spherical earth, between two lat-long points in degrees. */
inline double GreatCircleDistanceInMeters(double aLong1,double aLat1,double aLong2,double aLat2)
    {
    aLong1 *= KDegreesToRadiansDouble;
    aLat1 *= KDegreesToRadiansDouble;
    aLong2 *= KDegreesToRadiansDouble;
    aLat2 *= KDegreesToRadiansDouble;
    double 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;

    double angle = acos(cos_angle);
    return angle * KEquatorialRadiusInMetres;
    }

куда

const double KPiDouble = 3.141592654;
const double KDegreesToRadiansDouble = KPiDouble / 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;
person Graham Asher    schedule 12.09.2012
comment
Полностью согласен, что это правильно. Однако в то время не требовалось стопроцентной точности. - person Stuart Beard; 15.08.2014
comment
Вы все еще выбрали ответ, который опасно неверен вблизи полюсов, @StuartBeard, я всегда за приближения, где это уместно, но я думаю, что ваш выбор декартова расстояния в недекартовом пространстве в качестве ответа безответственен. - person Carl F.; 17.02.2016

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

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

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

person Ashutosh    schedule 09.12.2015
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. – Из обзора - person fasteque; 09.12.2015
comment
Спасибо за информацию @fasteque :) - person Ashutosh; 09.12.2015
comment
@fasteque решение, которое он упомянул, достаточно простое. Лучше включить в свой вопрос/предложение более подробную информацию о том, что именно вы хотите или ищете. - person Bhargav Nanekalva; 16.02.2016
comment
@NBhargav лучше включить соответствующую часть внешней ссылки или предоставить образец кода, если он станет недоступен. Это четко написано в руководстве по ответам: stackoverflow.com/help/how-to-answer. - person fasteque; 16.02.2016

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

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

_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 .

person Risadinha    schedule 12.04.2013

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

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

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

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

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

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

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

person Stuart Beard    schedule 18.12.2010
comment
Немного поздновато для вечеринки, но принимали ли вы во внимание тот факт, что используемая картографическая проекция искажает формы и расстояния между вещами? - person nyaray; 09.08.2013
comment
Это полностью игнорирует картографические проекции. Широта и долгота не равны друг другу! В северных и южных широтах он вообще не работает. Только возле экватора. Это не правильно. - person Carl F.; 12.07.2014
comment
@КарлФ. Да все верно. Есть лучшее решение при работе с картами. См. этот ответ stackoverflow.com/a/10428729/1202145 - person Bhargav Nanekalva; 16.02.2016
comment
@NBhargav, Ваша ссылка намного ближе к правильному ответу! Может еще есть проблемы. Я не проверял математику, но следите за приближением дуги к прямой линии. Может сделать Сидней, Австралия, намного ближе к Бостону, США. - person Carl F.; 17.02.2016