9

Mam dwa zestawy współrzędnych wieloboków wybranych z mapy geoJSON ulotki. rodzicem a dzieckiem współrzędne są współrzędnymi są:Sprawdź, czy punkt wielokątny znajduje się wewnątrz innej ulotki

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 
    ] 
] 

Dziecko wyciągnąć wewnątrz obszaru macierzystego, jak pokazano na rysunku: enter image description here

Korzystanie Ray Casting algorithm celu ustalenia, czy punkt leży wewnątrz wielokąta jestem nie jestem w stanie określić, kiedy otrzymuję wynik fałszywy. Proszę dać mi znać, gdzie robię źle lub w jakikolwiek inny sposób określić rozwiązanie. Dzięki

+0

Uwaga: łamanej wewnątrz wielokąta jego działa dobrze .Nie pracuje wielokąta wewnątrz wielokąta (jak pokazano na rysunku) – forgottofly

Odpowiedz

4

Próbowałem z twoim algorytmem i innym znaleźć tutaj https://rosettacode.org/wiki/Ray-casting_algorithm i oba zwracają właściwą wartość.

Może to skrzypce mogą pomóc w realizacji:

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

Twój 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)); 
} 

kod Rosetta 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

Mam dobre doświadczenia z Turf. Działa dobrze, jest dobrze udokumentowany, a przykłady są już pokazane z ulotką.

Dla Twojego problemu, można użyć turf.within z parentCoordinates jako turf.polygon i childCoordinates jako tablica turf.point:

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 ryba przykładowy.

1

Możesz wypróbować w tym celu aplet Ulotki - contains. Tworzysz wielokąt macierzysty za pomocą LatLngBounds, a następnie również dziecka.

parentPolygon.contains(childPolygon) 
+0

LatLngBounds tworzy prostokąt; plakat potrzebuje ogólnych wielokątów. Wycofane. –