Select to view content in your preferred language

Verify if XY is inside polygon

11493
40
Jump to solution
02-06-2017 01:23 PM
jaykapalczynski
Honored Contributor

Is there a way via JS or Python to simply pass an XY to a function and determine if inside or outside a polygon (from a map Service)

I need to do this for Decimal Degrees, DMS, UTM etc.

I can do it like below BUT I would have to list out EVERY node and trying to do this for a complete state

function inside(point, vs) {
    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;
};

var polygon = [[4040958.21,261090.239],[4399737.773,261090.239],  [4399737.773,1004118.285],[4040958.21,1004118.285]]                                                 

<!--// The below are two examples.  One of them is inside the other is outside to bounding box
// inside -->
test = inside([ 4147263, 646445.066 ], polygon); // true
<!-- // outside -->
<!--
test = inside([ 4537048, 694061 ], polygon); // false
 -->
alert(test);
40 Replies
RobertScheitlin__GISP
MVP Emeritus

Jay,

   Assuming that the query result would return one polygon (the one that you want to test the points against) then you would just use:

function addPointsToMap(results) {
   var polygon = results.features[0].geometry;
   .....
}‍‍‍‍
0 Kudos
jaykapalczynski
Honored Contributor

Something like this?

    require([
        "esri/tasks/query", "esri/tasks/QueryTask"], 
     function (
    Map, Query, QueryTask) {
          
     parser.parse();
     //Geometry Service
     var geometryService = new GeometryService("http://sampleserver5.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer");
     
     var query = new Query();
     var queryTask = new QueryTask( MY MAP SERVICE URL );
     query.outSpatialReference = {wkid:26917}; // UTM Zone 17 N 
     query.returnGeometry = true;
     queryTask.execute(query, getPoints);
  
     function addPointsToMap(results) {
        var polygon = results.features[0].geometry;
        var pnt = new Point(4147263, 646445.066, new SpatialReference({ wkid: your datas wkid # }));
       if (polygon.contains(pnt)){
               console.info("point is inside polygon");
          }else{
               console.info("point is NOT inside polygon");
          }
     } 
     
        });
    });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jay,

   That is pretty good assuming that you are omitting some requires and other code like the query.where clause for brevity sake.

0 Kudos
jaykapalczynski
Honored Contributor

Can I use something like below to get the polygon...there will only be 1

query.where = 1=1;
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Sure if the map service will only have one that will be fine.

0 Kudos
jaykapalczynski
Honored Contributor

OK maybe you can see something....

I get my map and I get my button.

I click the button and it ALERTS me "your in"

SO that had to have passed through the execute Function and then into the getPoints Function

Seems to be blowing up in the If Else Statement.....Thoughts?  I dont get any of the alerts from the If Else statement

<!DOCTYPE html>
<html>
<head>
  <title>Advanced Draw</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <link rel="stylesheet" href="http://js.arcgis.com/3.19/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.19/esri/css/esri.css">
  
  <script src="http://js.arcgis.com/3.19/"></script>

  <script>
    require([
        "esri/map", "dojo/ready", "dojo/parser", "esri/tasks/GeometryService", "esri/tasks/query", "esri/tasks/QueryTask", 
          "dojo/dom", "dojo/on", "dojo/domReady!"], 
     function (
    Map, ready, parser, GeometryService, Query, QueryTask, dom, on) {
    
     ready(function(){          
     parser.parse();
     //Geometry Service
     var geometryService = new GeometryService("https://sampleserver5.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer");

     //Add the Map/////////////////////////////////////////////////
     map = new Map("map", {
         basemap: "topo",
         center: [-80.734, 28.297],
         zoom: 10
     });


    function execute () {
          var query = new Query();
          var queryTask = new QueryTask("https://xxxxxx/arcgis/rest/services/Public/VirginiaBoundary/MapServer/0");
          query.outSpatialReference = {wkid:26917}; 
          query.where = "1=1";
          query.returnGeometry = true;
          queryTask.execute(query, getPoints);
    }

     function getPoints(results) {
        alert("your in");
        var polygon = results.features[0].geometry;
        var pnt = new Point(4147263, 646445.066, new SpatialReference({ wkid:26917}));
       if (polygon.contains(pnt)){
               console.info("point is inside polygon");
               alert("point is inside polygon");
          }else{
               console.info("point is NOT inside polygon");
               alert("point is NOT inside polygon");
          }
     } 

           //write "Get Details" button's click event 
     on(dom.byId("runQuery"), "click", execute);
  
        });
    });
  </script>

</head>
<body class="claro">
  <input type="button" value="Verify XY" id="runQuery" />

  <div id="map" style="width:600px; height:600px; border:1px solid #000;"></div>
</body>

</html>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
jaykapalczynski
Honored Contributor

Think I got it....As you mentioned earlier I was missing Requires....Once I get this working will post all code....Thanks for your help and guidance Robert

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Jay,

   Don't forget to mark this question as answered by clicking on the "Correct Answer" link on the reply that answered your question.

0 Kudos
jaykapalczynski
Honored Contributor

Will do just finalizing my code to post here and make sure everything works...Cheers

0 Kudos
jaykapalczynski
Honored Contributor

Last question...I am trying to test if inside my state.  UTM and Lat Long work great...but now looking at DMS and DMM

I can test on the DD fine...but it breaks when I try the other 2.  All locations below are in my state

DDD° MM' SS.S"      36° 51' 47.3" N 76° 0' 56.8" W

Degrees, Minutes and Seconds

DDD° MM.MMM'       36° 51.7884' N 76° 0.94668' W

Degrees and Decimal Minutes

DDD.DDDDD°           36.863140, -76.015778

Decimal Degrees

I try and type in the DMS and DMM in the format below but it fails everytime....BUT I can enter the DD fine and it works.

I enter them into 2 textboxes on my webpage as such

DMS

36 51 47.3   76 0 56.8

DMM

36 51.7884  76 0.94668

Any thoughts?

    function execute () {
          var query = new Query();
          var queryTask = new QueryTask("https://xxxx.gov/arcgis/rest/services/Public/Boundary/MapServer/0");
               
          if(document.getElementById('UTM17N').checked) {
               query.outSpatialReference = {wkid:26917}; 
          }else if(document.getElementById('DD').checked) {
               query.outSpatialReference = {wkid:4326}; 
          }else if(document.getElementById('DMS').checked) {
               query.outSpatialReference = {wkid:4326}; 
          }else if(document.getElementById('DDM').checked) {
               query.outSpatialReference = {wkid:4326}; 
          }
          // FINISH THE QUERY PARAMETERS AND CALL THE FUNCTION TO TEST
          query.where = "1=1";
          query.outFields = ["*"];
          query.returnGeometry = true;
          queryTask.execute(query, getPoints);
    }

     on(dom.byId("runQuery"), "click", execute);
     
     function getPoints(results) {
        var polygon = results.features[0].geometry;
        var XValue = document.getElementsByName('XCoord')[0].value
        var YValue = document.getElementsByName('YCoord')[0].value
        var TextBoxpnt = new Point((XValue), (YValue));
        if (polygon.contains(TextBoxpnt)){
               document.getElementById("p1").innerHTML = "point is inside polygon";     
          }else{
               document.getElementById("p1").innerHTML = "point is NOT inside polygon";
          }
     } 
0 Kudos