5つのセグメントを持つサンプルポリラインを設定しました。ユーザーがポリラインをクリックしたときに新しいマーカーを作成できるようにしています。
新しいマーカーがマーカー0と1の間、1と2の間、または4と5の間であるかどうかを判断する確実な方法があるかどうかを知りたいのですが、新しいマーカーが境界内にあるかどうかを確認することを検討しましたボックス、およびポイントインライン式ですが、どちらも100%正確ではありません。
5つのセグメントを持つサンプルポリラインを設定しました。ユーザーがポリラインをクリックしたときに新しいマーカーを作成できるようにしています。
新しいマーカーがマーカー0と1の間、1と2の間、または4と5の間であるかどうかを判断する確実な方法があるかどうかを知りたいのですが、新しいマーカーが境界内にあるかどうかを確認することを検討しましたボックス、およびポイントインライン式ですが、どちらも100%正確ではありません。
Googleマップは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);
}
ポイントとポリラインのすべてのセグメントをクリックすることで、上記の実装された関数を使用して、探しているセグメントを取得できます。