Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Offline spatial intersections in JS
//Example of using GeoJSON polygon data to do basic spatial intersections in iFormBuilder
//input GeoJSON data for zones, in WGS84 lat lon projection
var zones = JSON.parse('{"displayFieldName":"","fieldAliases":{"OBJECTID":"OBJECTID","ZONEID":"ZONEID","Shape_Length":"Shape_Length","Shape_Area":"Shape_Area"},"geometryType":"esriGeometryPolygon","spatialReference":{"wkid":4269,"latestWkid":4269},"fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID"},{"name":"ZONEID","type":"esriFieldTypeString","alias":"ZONEID","length":1},{"name":"Shape_Length","type":"esriFieldTypeDouble","alias":"Shape_Length"},{"name":"Shape_Area","type":"esriFieldTypeDouble","alias":"Shape_Area"}],"features":[{"attributes":{"OBJECTID":1,"ZONEID":"E","Shape_Length":4.0017220697931037,"Shape_Area":0.53018362362028371},"geometry":{"rings":[[[-69.430220952146556,44.442686473390495],[-69.514982657468863,43.831301610109222],[-69.505937590331087,43.836423752441988],[-69.500000001218723,43.801660000000993],[-69.500000001218723,43.650000000001455],[-69.273826274413295,43.042809128419321],[-69.536333332518552,42.891750000000684],[-69.813269644773754,43.646750947267719],[-69.83222882568225,43.644704426271346],[-69.864859999997861,43.720100000002276],[-69.854861893309135,43.745593786623431],[-69.830195656737487,43.865769495851055],[-69.855179996337029,43.945778872071969],[-69.981588862303397,43.881533425294037],[-69.913997298583126,44.336506198731513],[-69.430220952146556,44.442686473390495]]]}},{"attributes":{"OBJECTID":2,"ZONEID":"D","Shape_Length":5.1491688571235752,"Shape_Area":0.96688322764066326},"geometry":{"rings":[[[-68.825740756834421,44.313522220460072],[-68.926229999999123,44.175590000000739],[-68.999999999998181,44.103000000000975],[-69.00023000121837,44.075830000001588],[-68.991259999998874,44.013860000000932],[-68.96704999999929,43.966850000000704],[-68.956349999998565,43.969900000001871],[-68.953766667478703,43.955150000001595],[-68.894366667478607,43.928133332521611],[-68.972166629637286,43.904416678467896],[-68.971879998778604,43.850580001222625],[-69.001779999998689,43.850650000002133],[-68.988299999999072,43.776709998781371],[-68.964219999998022,43.791510001221468],[-68.905849999999191,43.745150000000649],[-68.834609999998065,43.58538000000226],[-68.737443767087825,43.327284831544603],[-69.000000092772098,43.200009155274529],[-69.273835883786887,43.042834923096962],[-69.500000001218723,43.650000000001455],[-69.500000001218723,43.801660000000993],[-69.513882473143894,43.831835501710884],[-69.035100297849567,45.015987858887456],[-68.517567529295775,44.753652282715848],[-68.738381510007457,44.362230947266653],[-68.825740756834421,44.313522220460072]]]}},{"attributes":{"OBJECTID":3,"ZONEID":"B","Shape_Length":2.8739003627481763,"Shape_Area":0.44729040820111621},"geometry":{"rings":[[[-68.487731434324814,44.169359896241076],[-68.48759390747,44.169404929200027],[-68.487673913572507,44.16958118774528],[-68.483179999999265,44.186870000001363],[-68.453719999997702,44.200390000001789],[-68.463339999998425,44.228329998781192],[-68.467909106444495,44.377075367432553],[-68.473027174070012,44.586400623780719],[-68.100403580321654,44.596394360352861],[-68.059921925047092,44.33182443847727],[-67.835367996824061,43.757120068361473],[-68.000070001218774,43.683350000001155],[-68.288066667479143,43.544400000000678],[-68.493792989500434,44.082731473390595],[-68.504858709715336,44.097163773194552],[-68.504654166257751,44.108618375244987],[-68.507569547116873,44.12741986328183],[-68.512149998778114,44.134350000002087],[-68.500709999998435,44.160320000000866],[-68.487673913572507,44.16958118774528],[-68.487731434324814,44.169359896241076]]]}},{"attributes":{"OBJECTID":4,"ZONEID":"A","Shape_Length":4.019577281623846,"Shape_Area":0.95413233860586044},"geometry":{"rings":[[[-67.205379999999423,45.171160000001692],[-67.190629999999146,45.165570000001026],[-67.158419999997932,45.16164000000208],[-67.129119999997783,45.132650000001377],[-67.112459999998464,45.112400000001799],[-67.094630001220139,45.074820000001637],[-67.021669999998267,44.953960000000734],[-66.99722000121983,44.928990000002159],[-66.968619999997827,44.910470000000714],[-66.98203999999896,44.867480000000796],[-66.974579999998241,44.841310000001613],[-66.965539999999237,44.829360000001543],[-66.931589999998323,44.825150000000576],[-66.885739999997895,44.794430000001739],[-66.93809000121837,44.744700000001103],[-66.958049999999275,44.653610000001208],[-67.01002999999946,44.61609000000135],[-67.049159999998665,44.5575000000008],[-67.04388999999901,44.510560000000623],[-67.06166999999914,44.484170000001541],[-67.037779999998747,44.42417000000205],[-67.042499999997744,44.361950000002253],[-67.143889999999374,44.235000000000582],[-67.279439999998431,44.186670000000959],[-67.358109999999215,43.970390000002226],[-67.835367996824061,43.757120068361473],[-68.059869999999137,44.331510001222341],[-68.059209447019384,44.594858814698455],[-67.205379999999423,45.171160000001692]]]}},{"attributes":{"OBJECTID":5,"ZONEID":"G","Shape_Length":3.4567025988643003,"Shape_Area":0.58857742469952923},"geometry":{"rings":[[[-70.098099999999249,43.547290000002249],[-69.722296140134858,42.525052978517124],[-70.603209998776947,42.967680000001565],[-70.612589999998818,42.979280000001381],[-70.627529998777391,42.981970000000729],[-70.689813382567081,43.034920115967907],[-70.833180418700067,43.125232784424952],[-70.302560614012691,43.745082375489801],[-70.098099999999249,43.547290000002249]]]}},{"attributes":{"OBJECTID":6,"ZONEID":"F","Shape_Length":3.7359021953716134,"Shape_Area":0.52455002788181515},"geometry":{"rings":[[[-69.830195656737487,43.865769495851055],[-69.854885194090457,43.745506795656183],[-69.864859999997861,43.720100000002276],[-69.83222882568225,43.644704426271346],[-69.813269644773754,43.646750947267719],[-69.536333332518552,42.891750000000684],[-69.667830001219045,42.816700000001219],[-69.667929998777254,42.497470000002068],[-69.877722355955484,42.603579970704232],[-70.196110001219495,43.48707000000104],[-70.145837698973992,43.528756575929947],[-70.198102481688693,43.563929116211511],[-70.362973059080105,43.674510887452925],[-70.033232089841476,43.926226840821982],[-69.981588862303397,43.881533425294037],[-69.855179996337029,43.945778872071969],[-69.830195656737487,43.865769495851055]]]}},{"attributes":{"OBJECTID":7,"ZONEID":"C","Shape_Length":3.4537753120952512,"Shape_Area":0.49209982358140369},"geometry":{"rings":[[[-68.972166629637286,43.904416678467896],[-68.916666667479149,43.921416667481026],[-68.980749999998807,43.947716667482382],[-68.978149999999005,43.963683332520304],[-68.967039999997723,43.96748000000116],[-68.991259999998874,44.013860000000932],[-69.00023000121837,44.075830000001588],[-68.999999999998181,44.103000000000975],[-68.926229999999123,44.175590000000739],[-68.827669999998761,44.311560000001919],[-68.738381510007457,44.362230947266653],[-68.638455286863973,44.329931446534829],[-68.473027174070012,44.586400623780719],[-68.463339999998425,44.228329998781192],[-68.453719999997702,44.200390000001789],[-68.483179999999265,44.186870000001363],[-68.487731434324814,44.169359896241076],[-68.500709999998435,44.160320000000866],[-68.512149998778114,44.134350000002087],[-68.507489999998143,44.127480000001015],[-68.518849999998565,44.113850000001548],[-68.518259999998918,44.10555000000204],[-68.507429999997839,44.103590000000622],[-68.494649999998728,44.082930000002307],[-68.288098874510979,43.544483724366728],[-68.737443767087825,43.327284831544603],[-68.834609999998065,43.58538000000226],[-69.032899999998335,43.748600000000806],[-68.988299999999072,43.776709998781371],[-69.001779999998689,43.850650000002133],[-68.971879998778604,43.850580001222625],[-68.972166629637286,43.904416678467896]]]}}]}')
//function to determine if x,y point is within polygon. The point argument is input as an x,y array and the polygon arg is an array of x,y arrays.
PointInPolygon = function (point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
// sourced from https://github.com/substack/point-in-polygon
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;
};
//function to take point and iterate through GeoJSON of zones, returning what zones the point is in
//argument point is an array representing the [lon, lat] of the point
//works with multi-part features but does not work with donut features
WhatZone = function (point) {
var inzones = [];
var x;
//iterate through features in json
for (x in zones.features) {
var zone = zones.features[x].attributes.ZONEID;
var y;
//iterate through parts of multi-part features
for (y in zones.features[x].geometry.rings) {
var polygon = zones.features[x].geometry.rings[y];
var inside = PointInPolygon(point, polygon);
if (inside === true && inzones.includes(zone) === false) {
inzones.push(zone);
}
}
}
return inzones.sort().toString();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment