Можно нарисовать линию кривой (например, геодезическую линию) между двумя близкими точками на картах Google, например, с этими координатами:
Спасибо.
Ответ 2
Недавно я выяснил другое решение, которое не нуждается в полилиниях, но использует значение пути для значков маркеров, которое можно вычислить "на лету".
Вкратце: вы просто создаете строку пути SVG для квадратичной кривой безье от 0 до p2-p1 и прикрепляете ее как значок маркера к p1.
Длинная версия:
Координаты пикселей внутри контейнера можно получить, вызвав google.maps.Projection.fromLatLngToContainerPixel()
.
Строка для квадратичной кривой безье выглядит следующим образом:
M [startX] [startY] q [controlX] [controlY] [endX] [endY]
Хорошо выберите (0,0)
для начальной точки, так как маркер будет позже помещен в эту точку. Относительное положение p2
теперь e = (p2.x - p1.x, p2.y - p1.y)
, а относительное положение
точки на полпути между ними m = (e.x/2, e.y/2)
. Ортогональным вектором к e
является o = s * norm(-e.x / e.y, 1)
, где s
- некоторый масштабный коэффициент с s = |e|/4
, являющийся хорошей отправной точкой. Теперь у нас есть
контрольная точка с c = (m.x + o.x, m.y + o.y)
, а путь:
path = „M 0 0 q c.x c.y e.x e.y"
Теперь, когда у нас есть этот путь, мы можем просто объявить значок:
var icon = {
path : path,
fillOpacity : 0,//important
scale : 1,
strokeOpacity: //yours,
strokeColor : //yours,
strokeWeight : //yours,
clickable : false //important
};
Настройка clickable
на значение false имеет важное значение, поскольку в противном случае область, заключенная в кривую, становится кликабельной, а базовая карта не получает события мыши. Теперь мы можем добавить маркер к карте с помощью
значок пути в качестве параметра и положение p1:
var marker = new google.maps.Marker({
position : p1,
icon : icon,
map : map,
clickable : false,
zIndex : -100 //make the line appear behind ‚real’ markers
});
Несколько замечаний:
- знак масштабирующего коэффициента ортогонального o определяет "направление" дуги ( "выше" или "ниже" e)
- Если уровень масштабирования изменяется, вам необходимо настроить масштабирование
иконки вроде этого:
marker.icon.scale = 1 / 2^(initialZoom -
currentZoom)
нет необходимости пересчитывать путь.
Пример:
![Sample of bezier curves on google maps]()
jsfiddle с жестким кодом с использованием исходных вопросов
соответствующий код:
var p1 = new google.maps.LatLng(23.634501, -102.552783);
var p2 = new google.maps.LatLng(17.987557, -92.929147);
var markerP1 = new google.maps.Marker({
position: p1,
map: map
});
var markerP2 = new google.maps.Marker({
position: p2,
map: map
});
google.maps.event.addListener(map, 'projection_changed', function () {
var p1 = map.getProjection().fromLatLngToPoint(markerP1.getPosition());
var p2 = map.getProjection().fromLatLngToPoint(markerP2.getPosition());
var e = new google.maps.Point(p1.x - p2.x, p1.y - p2.y);
var m = new google.maps.Point(e.x / 2, e.y / 2);
var o = new google.maps.Point(0, 7);
var c = new google.maps.Point(m.x + o.x, m.y + o.y);
var curveMarker2 = new google.maps.Marker({
position: markerP1.getPosition(),
icon: {
path: "M 0 0 q " + c.x + " " + c.y + " " + e.x + " " + e.y,
scale: 24,
strokeWeight: 2,
fillColor: '#009933',
fillOpacity: 0,
rotation: 180,
anchor: new google.maps.Point(0, 0)
}
});
curveMarker2.setMap(map);
google.maps.event.addListener(map, 'zoom_changed', function () {
var zoom = map.getZoom();
var scale = 1 / (Math.pow(2, -zoom));
var icon = {
path: "M 0 0 q " + c.x + " " + c.y + " " + e.x + " " + e.y,
scale: scale,
strokeWeight: 2,
fillColor: '#009933',
fillOpacity: 0,
rotation: 180,
anchor: new google.maps.Point(0, 0)
};
curveMarker2.setIcon(icon);
});
});