9

Ich habe zwei Sätze von Polygon-Koordinaten aus der Broschüre geoJSON Karte ausgewählt. Die Eltern und Kind-Koordinaten Koordinaten sind:Überprüfen Sie, ob ein Polygon-Punkt in einem anderen in der Broschüre ist

var parentCoordinates=[ 
    [ 
     32.05898221582174, 
     -28.31004731142091 
    ], 
    [ 
     32.05898221582174, 
     -28.308044824292978 
    ], 
    [ 
     32.06134255975485, 
     -28.308044824292978 
    ], 
    [ 
     32.06134255975485, 
     -28.31004731142091 
    ], 
    [ 
     32.05898221582174, 
     -28.31004731142091 
    ] 
] 
var childCoordinates=[ 
    [ 
    32.059904895722866, 
    -28.30970726909422 
    ], 
    [ 
    32.059904895722866, 
    -28.308743809931784 
    ], 
    [ 
    32.06089194864035, 
    -28.308743809931784 
    ], 
    [ 
    32.06089194864035, 
    -28.30970726909422 
    ], 
    [ 
    32.059904895722866, 
    -28.30970726909422 
    ] 
] 

das Kind in dem Mutterbereich gezogen wird, wie in der Abbildung dargestellt: enter image description here

Ray Casting algorithm, um festzustellen, ob der Punkt innerhalb Polygon liegt Ich bin nicht in der Lage zu bestimmen, wie das Ergebnis, das ich bekomme, falsch ist. Bitte lassen Sie mich wissen, wo ich falsch oder auf andere Weise, um die Lösung zu ermitteln bin. Danke

+0

Hinweis: Für Polylinie Innenpolygon seine Arbeits feiner .Nicht Arbeits für Polygon innerhalb Polygon (wie im Bild gezeigt) – forgottofly

Antwort

4

Ich habe versucht mit Ihrem Algorithmus und andere hier https://rosettacode.org/wiki/Ray-casting_algorithm gefunden und beide geben den richtigen Wert zurück.

Vielleicht Geige können Sie bei der Umsetzung helfen:

https://jsfiddle.net/4psL2hoo/1/

Ihre algo

// Data 
var parentCoordinates=[ 
    [ 
     32.05898221582174, 
     -28.31004731142091 
    ], 
    [ 
     32.05898221582174, 
     -28.308044824292978 
    ], 
    [ 
     32.06134255975485, 
     -28.308044824292978 
    ], 
    [ 
     32.06134255975485, 
     -28.31004731142091 
    ], 
    [ 
     32.05898221582174, 
     -28.31004731142091 
    ] 
] 
var childCoordinates=[ 
    [ 
    32.059904895722866, 
    -28.30970726909422 
    ], 
    [ 
    32.059904895722866, 
    -28.308743809931784 
    ], 
    [ 
    32.06089194864035, 
    -28.308743809931784 
    ], 
    [ 
    32.06089194864035, 
    -28.30970726909422 
    ], 
    [ 
    32.059904895722866, 
    -28.30970726909422 
    ] 
] 

// Other algo 
function test(point, vs) { 
    // ray-casting algorithm based on 
    // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html 

    var x = point[0], y = point[1]; 

    var inside = false; 
    for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) { 
     var xi = vs[i][0], yi = vs[i][1]; 
     var xj = vs[j][0], yj = vs[j][1]; 

     var intersect = ((yi > y) != (yj > y)) 
      && (x < (xj - xi) * (y - yi)/(yj - yi) + xi); 
     if (intersect) inside = !inside; 
    } 

    return inside; 
}; 

for (var i = 0; i < childCoordinates.length; i++) { 
    var testPoint = childCoordinates[i]; 
    console.log(JSON.stringify(testPoint) + '\tin parentCoordinate\t' + test(testPoint, parentCoordinates)); 
} 

Rosetta Code algo

//https://rosettacode.org/wiki/Ray-casting_algorithm 
function contains(bounds, lat, lng) { 
    //https://rosettacode.org/wiki/Ray-casting_algorithm 
    var count = 0; 
    for (var b = 0; b < bounds.length; b++) { 
     var vertex1 = bounds[b]; 
     var vertex2 = bounds[(b + 1) % bounds.length]; 
     if (west(vertex1, vertex2, lng, lat)) 
      ++count; 
    } 
    return count % 2; 

    /** 
    * @return {boolean} true if (x,y) is west of the line segment connecting A and B 
    */ 
    function west(A, B, x, y) { 
     if (A.y <= B.y) { 
      if (y <= A.y || y > B.y || 
       x >= A.x && x >= B.x) { 
       return false; 
      } else if (x < A.x && x < B.x) { 
       return true; 
      } else { 
       return (y - A.y)/(x - A.x) > (B.y - A.y)/(B.x - A.x); 
      } 
     } else { 
      return west(B, A, x, y); 
     } 
    } 
} 

var square = {name: 'square', bounds: [{x: 32.05898221582174, y: -28.31004731142091}, {x: 32.05898221582174, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.31004731142091}]}; 

var shapes = [square]; 
var testPoints = [{lng: 32.059904895722866, lat: -28.30970726909422}, {lng: 32.059904895722866, lat: -28.308743809931784}, {lng: 32.06089194864035, lat: -28.308743809931784}, 
    {lng: 32.06089194864035, lat: -28.30970726909422}]; 

for (var s = 0; s < shapes.length; s++) { 
    var shape = shapes[s]; 
    for (var tp = 0; tp < testPoints.length; tp++) { 
     var testPoint = testPoints[tp]; 
     console.log(JSON.stringify(testPoint) + '\tin ' + shape.name + '\t' + contains(shape.bounds, testPoint.lat, testPoint.lng)); 
    } 
} 
4

Ich habe gute Erfahrungen mit Turf gemacht. Es funktioniert gut, ist gut dokumentiert und die Beispiele sind bereits mit einem Faltblatt gezeigt.

Für Ihr Problem, könnte man turf.within mit parentCoordinates als turf.polygon und childCoordinates als ein Array von turf.point verwenden:

var parentPolygon = turf.polygon([parentCoordinates]); 

var inside = true; 
childCoordinates.forEach(function(coordinates) { 
    point = turf.point(coordinates); 
    if (!turf.inside(point, parentPolygon)){ 
     alert("Oh no! "+ coordinates + " isn't in polygon"); 
     inside = false; 
    } 
}); 

alert("Child polygon inside parent polygon ? " + inside); 

Here ‚s ein Fiddle Beispiel.

1

Sie können Leaflet's API dafür versuchen - contains. Sie erstellen ein Eltern-Polygon mit LatLngBounds und dann auch Kind.

parentPolygon.contains(childPolygon) 
+0

LatLngBounds ein Rechteck bildet; Das Poster benötigt allgemeine Polygone. Downvoted. –

Verwandte Themen