Карты Google - широта X% вдоль прямой ломаной линии

Мне нужно получить широту / долготу позиции в процентах X вдоль отрезка прямой ломаной линии между двумя другими точками широты / долготы.

Самое близкое, что я до сих пор использовал, - это использовать следующее (для 40% по линии):

google.maps.geometry.spherical.interpolate(startLatLng, endLatLng, 0.4);

Это отлично работает для коротких расстояний, однако для длинного сегмента полилинии возвращенная широта находится за пределами того места, где проходит полилиния, поскольку он определяет кратчайшее расстояние по поверхности земли вместо кратчайшего расстояния по плоской карте.

Любая помощь по этому поводу будет оценена, надеюсь, мне просто не хватает чего-то очевидного.


person zedeso    schedule 05.04.2013    source источник
comment
+1 .. Блестящий вопрос ..   -  person writeToBhuwan    schedule 02.05.2013


Ответы (2)


Для этого должен существовать какой-то проверенный и проверенный метод, но вот способ, которым вы можете сделать это с помощью Maps API:

  1. Преобразование координат широты и долготы в пиксели
  2. Интерполировать в пиксельной плоскости
  3. Конвертировать обратно в широту / долготу

В основном это довольно просто; единственная проблема - выяснить, как поступать с линиями, пересекающими 180-й меридиан или полюс.

Вот несколько полутестированных кодов, с которых можно начать:

function mercatorInterpolate( map, latLngFrom, latLngTo, fraction ) {
    // Get projected points
    var projection = map.getProjection();
    var pointFrom = projection.fromLatLngToPoint( latLngFrom );
    var pointTo = projection.fromLatLngToPoint( latLngTo );
    // Adjust for lines that cross the 180 meridian
    if( Math.abs( pointTo.x - pointFrom.x ) > 128 ) {
        if( pointTo.x > pointFrom.x )
            pointTo.x -= 256;
        else
            pointTo.x += 256;
    }
    // Calculate point between
    var x = pointFrom.x + ( pointTo.x - pointFrom.x ) * fraction;
    var y = pointFrom.y + ( pointTo.y - pointFrom.y ) * fraction;
    var pointBetween = new google.maps.Point( x, y );
    // Project back to lat/lng
    var latLngBetween = projection.fromPointToLatLng( pointBetween );
    return latLngBetween;
}

Я не уверен на 100% насчет части, которая обрабатывает линии, пересекающие 180-меридиан, но она работает нормально в нескольких быстрых тестах, которые я пробовал.

person Michael Geary    schedule 05.04.2013
comment
Это определенно позаботится об этом, если ломаная линия не пересекает 180-й меридиан. Мы будем очень благодарны за любой совет о том, с чего начать с проблемой 180 меридианов. Кроме того, пересечение полюсов не должно быть проблемой с картами Google, не так ли? - person zedeso; 06.04.2013
comment
Я добавил немного кода для обработки пересечения 180 градусов. Я думаю, что это может быть правильно, но только немного проверил это. Будет любопытно узнать, работает ли это ... - person Michael Geary; 06.04.2013

См. Это обсуждение в Google Maps Группа API v3

И этот пример из него

Этот предлагаемый код учитывает проекцию для средней точки:

google.maps.event.addListener(map, 'projection_changed', function() {
  var projection = map.getProjection();
  if (!projection) return;

  // Project
  var startLatLng = startMarker.getPosition();
  var endLatLng = endMarker.getPosition();
  var startPoint = projection.fromLatLngToPoint(startLatLng);
  var endPoint = projection.fromLatLngToPoint(endLatLng);

  // Average
  var midPoint = new google.maps.Point(
      (startPoint.x + endPoint.x) / 2,
      (startPoint.y + endPoint.y) / 2);

  // Unproject
  var midLatLng = projection.fromPointToLatLng(midPoint);
  midMarker.setPosition(midLatLng);

}); 
person geocodezip    schedule 05.04.2013