Search code examples
javascriptalgorithmgpsturfjs

Turf JS Intersection issues


I am encountering some issues finding if two polygons intersect each other with turfs.

What is the purpose of my code?

  • Given an asset's position ( coordinates ), Field of View ( betweeen -180 and 180, simulated of course ) and a distance ( I call it vision range; let's say 1 kilometer ), I want to know if the asset can "see" if another asset is in range. Think about a lion meets another lion and they will fight on sight.

The code:

function calculateFOV(origin,fov,distance) {
    let turf = require('@turf/turf');

   var pontoOrigem = turf.point([origin.long, origin.lat]); //setup the origin
   var pontosDestino = []; //prepare the array that contains the making of the polygon I want to intersect

   if (campo.length == 2) {    
       var bearing = 90; //always 90 for now
       var options = {units: 'kilometers'};
       for(var bearing=fov[0]; bearing<=fov[1]; bearing+=10) {                   

           pontosDestino.push(turf.getCoord(turf.destination(pontoOrigem, distance/1000, bearing, options)));           
       }
       //if (pontosDestino.length > 0) pontosDestino.push(pontosDestino[0]); //equal the to the first element so that turf does not complain about the last element not being equal to the first
    }              
    return pontosDestino;        
}

var poly1 = calculateFOV({'long' :-7.9554464, 'lat':37.0100746},[-180,180],1);
var poly2 = calculateFOV({'long' :-7.9322, 'lat':37.0194},[-180,180],1);

poly1 returns:

[
  [ -7.955446399999999, 37.01006560679637 ],
  [ -7.955448355660866, 37.010065743423326 ],
  [ -7.955450251899985, 37.01006614915285 ],
  [ -7.955452031101114, 37.01006681165707 ],
  [ -7.955453639204135, 37.010067710806105 ],
  [ -7.9554550273476625, 37.01006881927983 ],
  [ -7.955456153353656, 37.01007010339779 ],
  [ -7.955456983008984, 37.01007152414274 ],
  [ -7.95545749110498, 37.010073038346064 ],
  [ -7.955457662203383, 37.01007459999947 ],
  [ -7.9554574911054345, 37.01007616165291 ],
  [ -7.955456983009841, 37.01007767585633 ],
  [ -7.955456153354809, 37.01007909660142 ],
  [ -7.955455027348974, 37.01008038071956 ],
  [ -7.955453639205447, 37.01008148919346 ],
  [ -7.9554520311022685, 37.01008238834268 ],
  [ -7.955450251900842, 37.01008305084704 ],
  [ -7.9554483556613205, 37.01008345657665 ],
  [ -7.955446399999999, 37.010083593203646 ],
  [ -7.955444444338677, 37.01008345657665 ],
  [ -7.955442548099154, 37.01008305084704 ],
  [ -7.95544076889773, 37.01008238834268 ],
  [ -7.95543916079455, 37.01008148919346 ],
  [ -7.955437772651024, 37.01008038071956 ],
  [ -7.95543664664519, 37.01007909660142 ],
  [ -7.955435816990157, 37.01007767585633 ],
  [ -7.955435308894563, 37.01007616165291 ],
  [ -7.955435137796615, 37.01007459999947 ],
  [ -7.955435308895018, 37.010073038346064 ],
  [ -7.955435816991014, 37.01007152414274 ],
  [ -7.9554366466463415, 37.01007010339779 ],
  [ -7.955437772652336, 37.01006881927983 ],
  [ -7.955439160795862, 37.010067710806105 ],
  [ -7.955440768898884, 37.01006681165707 ],
  [ -7.955442548100012, 37.01006614915285 ],
  [ -7.955444444339133, 37.010065743423326 ],
  [ -7.955446399999999, 37.01006560679637 ]
]

poly2 returns:

[
  [ -7.9322, 37.01939100679636 ],
  [ -7.932201955900867, 37.01939114342331 ],
  [ -7.9322038523726945, 37.019391549152836 ],
  [ -7.9322056317921685, 37.01939221165705 ],
  [ -7.932207240092537, 37.0193931108061 ],
  [ -7.9322086284064195, 37.01939421927982 ],
  [ -7.932209754550595, 37.019395503397774 ],
  [ -7.932210584307741, 37.019396924142725 ],
  [ -7.93221109246609, 37.01939843834605 ],
  [ -7.932211263585491, 37.019399999999465 ],
  [ -7.932211092466545, 37.0194015616529 ],
  [ -7.932210584308598, 37.019403075856324 ],
  [ -7.932209754551749, 37.01940449660141 ],
  [ -7.932208628407731, 37.01940578071955 ],
  [ -7.932207240093851, 37.01940688919345 ],
  [ -7.932205631793323, 37.019407788342676 ],
  [ -7.932203852373552, 37.01940845084703 ],
  [ -7.932201955901323, 37.019408856576646 ],
  [ -7.9322, 37.01940899320363 ],
  [ -7.932198044098676, 37.019408856576646 ],
  [ -7.932196147626447, 37.01940845084703 ],
  [ -7.932194368206678, 37.019407788342676 ],
  [ -7.932192759906149, 37.01940688919345 ],
  [ -7.9321913715922685, 37.01940578071955 ],
  [ -7.9321902454482505, 37.01940449660141 ],
  [ -7.932189415691402, 37.019403075856324 ],
  [ -7.932188907533454, 37.0194015616529 ],
  [ -7.932188736414509, 37.019399999999465 ],
  [ -7.93218890753391, 37.01939843834605 ],
  [ -7.932189415692259, 37.019396924142725 ],
  [ -7.932190245449405, 37.019395503397774 ],
  [ -7.93219137159358, 37.01939421927982 ],
  [ -7.932192759907462, 37.0193931108061 ],
  [ -7.932194368207832, 37.01939221165705 ],
  [ -7.932196147627304, 37.019391549152836 ],
  [ -7.932198044099133, 37.01939114342331 ],
  [ -7.9322, 37.01939100679636 ]
]

turf.intersect(poly1,poly2) on node, exits with this message:

Error: geojson must be a valid Feature or Geometry Object at getGeom (/home/pedroh/Documentos/Faro/node_modules/@turf/turf/turf.js:1909:11) at Object.intersect$2 [as intersect] (/home/pedroh/Documentos/Faro/node_modules/@turf/turf/turf.js:43369:17) at Object. (/home/pedroh/Documentos/Faro/_test_turf.js:11:6)

Then with a second version of the function,

function calculateFOV(origin,fov,distance) {
    let turf = require('@turf/turf');

   var pontoOrigem = turf.point([origin.long, origin.lat]); //setup the origin
   var pontosDestino = []; //prepare the array that contains the making of the polygon I want to intersect

   if (campo.length == 2) {    
       var bearing = 90; //always 90 for now
       var options = {units: 'kilometers'};
       for(var bearing=fov[0]; bearing<=fov[1]; bearing+=10) {                   
           pontosDestino.push(turf.destination(pontoOrigem, distance/1000, bearing, options));
       }
       //if (pontosDestino.length > 0) pontosDestino.push(pontosDestino[0]); //equal the to the first element so that turf does not complain about the last element not being equal to the first
    }              
    return pontosDestino;        
}

var poly1 = calculateFOV({'long' :-7.9554464, 'lat':37.0100746},[-180,180],1);
var poly2 = calculateFOV({'long' :-7.9322, 'lat':37.0194},[-180,180],1);

poly1 and poly2 returns something like this:

[
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  },
  {
    type: 'Feature',
    properties: {},
    geometry: { type: 'Point', coordinates: [Array] }
  }
]

Node exits with same error.

Am I missing something, or It's something with the code?

UPDATED FUNCTION after accepted answer

function calculateFOV(origem,campo,distancia_focal,bearing) {
    let turf = require('@turf/turf');

   var pontoOrigem = turf.point([origem.long, origem.lat]);
   var pontosDestino = [];
   pontosDestino.push([]);

   if (campo.length == 2) {           
       var options = {units: 'kilometers'};
       for(var bearing=campo[0]; bearing<=campo[1]; bearing+=10) {                   
            //esta linha é comentada porque o resultado final tem um tipo manhoso
           //pontosDestino.push(turf.destination(pontoOrigem, distancia_focal/1000, bearing, options));


           pontosDestino[0].push(turf.getCoord(turf.destination(pontoOrigem, distancia_focal/1000, bearing, options)));           
       }
       //igualar o último ponto para que o turf não bitcha sobre pontos equivalentes. faz sentido porque os polígonos têm de ser fechados
       if (JSON.stringify(pontosDestino[0][0]) != JSON.stringify(pontosDestino[0][pontosDestino[0].length-1])) {
        pontosDestino[0].push(pontosDestino[0][0]);                       
       }       
    }              
    return pontosDestino;        
}

//testing function
function testIntersection(poly1,poly2) {    
    if (typeof poly1 !== 'undefined' && typeof poly2 !== 'undefined') {        
        console.log("intersection");
        //test intersection with two turf features
        let turf = require('@turf/turf');        
        let polygon1 = turf.polygon(poly1);
        let polygon2 = turf.polygon(poly2);
        /* test intersection */    
        return turf.intersect(polygon1, polygon2);   

    }
    else {
        return -1; //error code given if I don't have both asset's positions at time of check
    }    
}

Solution

  • Not sure if this helps (never used Turf JS before), but if I take your poly1 and poly2 and place them in a minimal script, the result of the intersection is null. Per https://turfjs.org/docs/#intersect, this indicates "they do not share any point".

    <html><head>
    <script src='https://npmcdn.com/@turf/turf/turf.min.js'></script>
    <script>
    var poly1 = turf.polygon([[
      [ -7.955446399999999, 37.01006560679637 ],
      [ -7.955448355660866, 37.010065743423326 ],
      [ -7.955450251899985, 37.01006614915285 ],
      [ -7.955452031101114, 37.01006681165707 ],
      [ -7.955453639204135, 37.010067710806105 ],
      [ -7.9554550273476625, 37.01006881927983 ],
      [ -7.955456153353656, 37.01007010339779 ],
      [ -7.955456983008984, 37.01007152414274 ],
      [ -7.95545749110498, 37.010073038346064 ],
      [ -7.955457662203383, 37.01007459999947 ],
      [ -7.9554574911054345, 37.01007616165291 ],
      [ -7.955456983009841, 37.01007767585633 ],
      [ -7.955456153354809, 37.01007909660142 ],
      [ -7.955455027348974, 37.01008038071956 ],
      [ -7.955453639205447, 37.01008148919346 ],
      [ -7.9554520311022685, 37.01008238834268 ],
      [ -7.955450251900842, 37.01008305084704 ],
      [ -7.9554483556613205, 37.01008345657665 ],
      [ -7.955446399999999, 37.010083593203646 ],
      [ -7.955444444338677, 37.01008345657665 ],
      [ -7.955442548099154, 37.01008305084704 ],
      [ -7.95544076889773, 37.01008238834268 ],
      [ -7.95543916079455, 37.01008148919346 ],
      [ -7.955437772651024, 37.01008038071956 ],
      [ -7.95543664664519, 37.01007909660142 ],
      [ -7.955435816990157, 37.01007767585633 ],
      [ -7.955435308894563, 37.01007616165291 ],
      [ -7.955435137796615, 37.01007459999947 ],
      [ -7.955435308895018, 37.010073038346064 ],
      [ -7.955435816991014, 37.01007152414274 ],
      [ -7.9554366466463415, 37.01007010339779 ],
      [ -7.955437772652336, 37.01006881927983 ],
      [ -7.955439160795862, 37.010067710806105 ],
      [ -7.955440768898884, 37.01006681165707 ],
      [ -7.955442548100012, 37.01006614915285 ],
      [ -7.955444444339133, 37.010065743423326 ],
      [ -7.955446399999999, 37.01006560679637 ]
    ]]);
    
    var poly2 = turf.polygon([[
      [ -7.9322, 37.01939100679636 ],
      [ -7.932201955900867, 37.01939114342331 ],
      [ -7.9322038523726945, 37.019391549152836 ],
      [ -7.9322056317921685, 37.01939221165705 ],
      [ -7.932207240092537, 37.0193931108061 ],
      [ -7.9322086284064195, 37.01939421927982 ],
      [ -7.932209754550595, 37.019395503397774 ],
      [ -7.932210584307741, 37.019396924142725 ],
      [ -7.93221109246609, 37.01939843834605 ],
      [ -7.932211263585491, 37.019399999999465 ],
      [ -7.932211092466545, 37.0194015616529 ],
      [ -7.932210584308598, 37.019403075856324 ],
      [ -7.932209754551749, 37.01940449660141 ],
      [ -7.932208628407731, 37.01940578071955 ],
      [ -7.932207240093851, 37.01940688919345 ],
      [ -7.932205631793323, 37.019407788342676 ],
      [ -7.932203852373552, 37.01940845084703 ],
      [ -7.932201955901323, 37.019408856576646 ],
      [ -7.9322, 37.01940899320363 ],
      [ -7.932198044098676, 37.019408856576646 ],
      [ -7.932196147626447, 37.01940845084703 ],
      [ -7.932194368206678, 37.019407788342676 ],
      [ -7.932192759906149, 37.01940688919345 ],
      [ -7.9321913715922685, 37.01940578071955 ],
      [ -7.9321902454482505, 37.01940449660141 ],
      [ -7.932189415691402, 37.019403075856324 ],
      [ -7.932188907533454, 37.0194015616529 ],
      [ -7.932188736414509, 37.019399999999465 ],
      [ -7.93218890753391, 37.01939843834605 ],
      [ -7.932189415692259, 37.019396924142725 ],
      [ -7.932190245449405, 37.019395503397774 ],
      [ -7.93219137159358, 37.01939421927982 ],
      [ -7.932192759907462, 37.0193931108061 ],
      [ -7.932194368207832, 37.01939221165705 ],
      [ -7.932196147627304, 37.019391549152836 ],
      [ -7.932198044099133, 37.01939114342331 ],
      [ -7.9322, 37.01939100679636 ]
    ]]);
    
    var intersection = turf.intersect( poly1, poly2 );
    
    console.log( intersection );
    </script>
    
    </head><body>
    
    </body></html>

    More to the point, the example in the documentation at https://turfjs.org/docs/#intersect shows a triple nested array for the polygons. The only tweak I made was to ensure that poly1 and poly2 are triple nested arrays, whereas your question above shows poly1 and poly2 being double nested arrays.

    Hope this helps.