0

Ich habe eine sample polyline with five segments eingerichtet, und ich erlaube neue Markierungen erstellt werden, wenn der Benutzer auf die Polylinie klickt.Auf welches Segment einer Polylinie wurde geklickt?

Ich würde gerne wissen, ob es einen idiotensicheren Weg gibt zu bestimmen, ob der neue Marker zwischen Marker 0 und 1 oder 1 und 2 ... oder zwischen 4 und 5 ist. Ich überlegte, ob der neue Marker überprüft werden soll ist innerhalb einer Bounding-Box und Point-in-Line-Formeln, aber keiner ist 100% genau.

Antwort

5

Wie Google Maps Mercator Projection verwendet für die GPS-Koordinaten Projizieren, können Sie nicht für die GPS-Koordinaten verwenden ‚Liniengleichung‘, weil Projektion nicht für die GPS-linear ist points.But stattdessen können Sie world coordinates verwenden, die linear sind. Hier habe ich parametrische Form von Liniengleichung verwendet ob point auf dem Segment zu überprüfen:

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); 
} 

Durch Anklicken Punkt und alle Segmente der Polylinie, könnten Sie oben implementierte Funktion nutzen und abrufen Segment, das Sie gesucht haben.

+0

Beste Lösung, die ich gesehen habe. Es bricht nur (Division durch Null), wenn Segmente genau horizontal oder vertikal sind, aber dies ist in der Praxis unwahrscheinlich, da der Benutzer die Markierungen von Hand platziert. –

+0

@HeitorChang Ah, ja, du hast recht über horizontale und vertikale Fälle, die ich verpasst habe. Ich habe meine Antwort aktualisiert. Bitte prüfe. – Engineer

+0

Danke, dass Sie gründlich sind. Ich würde wieder upvote wenn ich könnte :) –

Verwandte Themen