0

我已经设置了一条包含五个段的示例折线,并且当用户单击折线时,我允许创建新的标记。

我想知道是否有一种万无一失的方法来确定新标记是在标记 0 和 1 之间,还是在 1 和 2 之间……或者在 4 和 5 之间。我考虑过检查新标记是否在边界内框和直线公式,但都不是 100% 精确的。

4

1 回答 1

5

由于谷歌地图使用墨卡托投影来投影 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);
} 

通过单击点和折线的所有线段,您可以使用上述实现的功能并检索您正在寻找的线段。

于 2012-04-05T08:07:37.223 回答