Поскольку Google Maps использует Mercator Projection для проецирования координат GPS, вы не можете использовать «линейное уравнение» для координат gps, поскольку проекция не является линейной для точек gps. Но вместо этого вы можете использовать world coordinates
, которые являются линейными. Здесь я использовал параметрическую форму уравнения линии проверить, является ли point
на сегменте:
function isPointOnSegment(map, gpsPoint1, gpsPoint2, gpsPoint){
var p1 = map.getProjection().fromLatLngToPoint(gpsPoint1);
var p2 = map.getProjection().fromLatLngToPoint(gpsPoint2);
var p = map.getProjection().fromLatLngToPoint(gpsPoint);
var t_x;
var t_y;
//Parametric form of line equation is:
//--------------------------------
// x = x1 + t(x2-x1)
// y = y1 + t(y2-y1)
//--------------------------------
//'p' is on [p1,p2] segment,if 't' is number from [0,1]
//-----Case 1----
// x = x1
// y = y1
//---------------
if(p2.x-p1.x == 0 && p2.y-p1.y == 0){
return p.x == p1.x && p.y == p1.y;
}else
//-----Case 2----
// x = x1
// y = y1 + t(y2-y1)
//---------------
if(p2.x-p1.x == 0 && p2.y-p1.y != 0){
t_y = (p.y - p1.y)/(p2.y-p1.y);
return p.x == p1.x && t_y >= 0 && t_y <= 1;
}else
//-----Case 3----
// x = x1 + t(x2-x1)
// y = y1
//---------------
if(p2.x-p1.x != 0 && p2.y-p1.y == 0){
t_x = (p.x - p1.x)/(p2.x-p1.x);
return p.y == p1.y && t_x >= 0 && t_x <= 1;
}
//-----Case 4----
// x = x1 + t(x2-x1)
// y = y1 + t(y2-y1)
//---------------
t_x = (p.x - p1.x)/(p2.x-p1.x);
t_y = (p.y - p1.y)/(p2.y-p1.y);
return (t_x == t_y && t_x >= 0 && t_x <= 1 && t_y >= 0 && t_y <= 1);
}
Имея нажатую точку и все сегменты полилинии, вы можете использовать выше реализованную функцию и извлечение сегмента, который вы искали.
Лучшее решение, которое я видел. Он только разбивается (деление на ноль), если сегменты точно горизонтальны или вертикальны, но это вряд ли произойдет на практике, так как у меня есть пользователь, который помещает маркеры вручную. –
@HeitorChang Ах, да, вы правы в горизонтальных и вертикальных случаях, которые я пропустил. Я обновил свой ответ. Пожалуйста, проверьте. – Engineer
Спасибо за тщательность. Я бы поднял голову, если бы мог :) –