Created
February 1, 2016 16:29
-
-
Save raykendo/f174b3c95c5d581f73e6 to your computer and use it in GitHub Desktop.
Finding a point within a geometry for ArcGIS JavaScript API using client-side processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
"dojo/_base/array", | |
"esri/geometry/Polygon", | |
"esri/geometry/Polyline", | |
"esri/geometry/Point", | |
"esri/geometry/geometryEngine" | |
], function (arrayUtils, Polygon, Polyline, Point, geometryEngine) { | |
/** | |
* Finds a point on a polyline | |
* @function pointFromLine | |
* @param {"esri/geometry/Polyline"} polyline - the polyline to get points from | |
* @param {"esri/geometry/Polygon"} [testPolygon] - if a polygon is used to determine clickability, return | |
* @returns {"esri/geometry/Point"} a point that should be contained in the polyline, and polygon (if provided); | |
*/ | |
function pointFromLine(polyline, testPolygon) { | |
var resultPoint = null; | |
arrayUtils.some(polyline.paths, function (path) { | |
var numSegments = path.length - 1, | |
segmentPointer, segmentEnd, avgPointCoords; | |
for (segmentPointer = 0; segmentPointer < numSegments; segmentPointer++) { | |
segmentEnd = path[segmentPointer + 1]; | |
avgPointCoords = arrayUtils.map(path[segmentPointer], function (coord, index) { | |
return (coord + segmentEnd[index]) / 2; | |
}); | |
if (!testPolygon || testPolygon.contains(new Point(avgPointCoords).setSpatialReference(polyline.spatialReference))) { | |
resultPoint = new Point(avgPointCoords).setSpatialReference(polyline.spatialReference); | |
break; | |
} | |
} | |
return !!resultPoint; | |
}); | |
return resultPoint; | |
} | |
/** | |
* finds a point contained within a polygon | |
* @function pointFromPolygon | |
* @param {"esri/geometry/Polygon"} polygon | |
* @returns {"esri/geometry/Point"} - a point that should be contained in the polygon | |
*/ | |
function pointFromPolygon(polygon) { | |
var intersects, resultLine; | |
arrayUtils.some(polygon.rings, function(ring) { | |
// make a polygon from the first ring and get its extent. | |
var polygonFromRing = new Polygon(ring).setSpatialReference(polygon.spatialReference), | |
extent = polygonFromRing.getExtent(), | |
yAvg, yAvgLine, xAvg, xAvgLine; | |
// draw a horizontal line that should go through the middle of the current ring | |
yAvg = (extent.ymin + extent.ymax) / 2; | |
yAvgLine = new Polyline([ | |
[extent.xmin, yAvg], | |
[extent.xmax, yAvg] | |
]).setSpatialReference(polygon.spatialReference); | |
// test if the horizontal line intersects the whole polygon somehow. | |
intersects = geometryEngine.intersects(yAvgLine, polygon); | |
if (intersects) { | |
// if so, create the intersection line from that line | |
resultLine = geometryEngine.intersect(yAvgLine, polygon); | |
return intersects; | |
} | |
// draw a vertical line that should go through the middle of the current ring | |
xAvg = (extent.xmin + extent.xmax) / 2; | |
xAvgLine = new Polyline([ | |
[xAvg, extent.ymin], | |
[xAvg, extent.ymax] | |
]).setSpatialReference(polygon.spatialReference); | |
// test if the vertical line interesects with the whole polygon | |
intersects = geometryEngine.intersects(xAvgLine, polygon); | |
if (intersects) { | |
// if intersects, create an intersecting line between the two shapes. | |
resultLine = geometryEngine.intersect(yAvgLine, polygon); | |
} | |
return intersects; | |
}); | |
if (intersects) { | |
return pointFromLine(resultLine, polygon); | |
} | |
return null; | |
} | |
/** | |
* Finds a point that is certain to be contained within another geometry | |
* @function PointWithin | |
* @param {object} geometry - an ArcGIS JavaScript API Geometry | |
* See https://developers.arcgis.com/javascript/jsapi/geometry-amd.html | |
* @returns {object} and ArcGIS JavsScript API Point Geometry that should be within it. | |
*/ | |
return function (geometry) { | |
if (!geometry.type) { | |
throw "Invalid geometry passed to the function"; | |
return; | |
} | |
if (geometry.type === "point") { | |
return geometry; | |
} | |
if (geometry.type === "extent") { | |
return geometry.getCenter(); | |
} | |
if (geometry.type === "multipoint") { | |
return geometry.getPoint(0); | |
} | |
if (geometry.type === "polyline") { | |
return pointFromLine(geometry); | |
} | |
if (geometry.type === "polygon") { | |
return pointFromPolygon(geometry); | |
} | |
throw "Unknown geometry type: " + geometry.type; | |
}; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment