3

Using a Python script, we are pulling a list of polygon vertices from a web service to build a polygon and insert it into our SDE.

The problem steps are happening when we're making an arcpy.Polygon geometry object out of an arcpy.Array of arcpy.Points. There are 95 points listed in the JSON, 95 points in the polygon_array... and then not 95 points in the resulting arcpy.Polygon.

  • If it's created with no spatial reference, the polygon pointCount has 11 points
  • If it's created with WGS84 (which matches the lat/long projection of the source data), the polygon pointCount has 1126 (!) points

Why does the resulting polygon have such a different number of vertices (either less or more) than it's being handed? Is it possible for misordered vertices that would cause geometry problems to be "weeded out" by the arcpy.Polygon instantiation — but if so, I'm even more baffled by the WGS84 polygon having over a thousand points!

Code below:

# add points to array
polygon_array = arcpy.Array()
for point in polygon_data:
    polygon_array.add(
        arcpy.Point(
            polygon_data[point]['Value']['Longitude'],
            polygon_data[point]['Value']['Latitude']
        )
    )

# print the length of the array of points
print(polygon_array.count) # prints 95

sr = arcpy.SpatialReference(4326)
polygonObj = arcpy.Polygon(polygon_array, sr)

# Print the amount of points in our polygon
print(polygonObj.pointCount) # prints 1126

(This is running with ArcGIS Desktop 10.2.1.)

  • I'm not sure why the number of points could increase but I could see why they reduce. Sounds like the environment settings for XY tolerance or clustering have been altered? I would look there first? – Hornbydd Aug 30 '18 at 14:42
  • 4
    It's always a mistake to not specify a SpatialReference when creating a geometry. The reason is that a SpatialReference is required, and if you don't provide a proper one, ArcGIS will provide an improper one. In this case, the XY Resolution is probably 0.001 units, which produces a generalized polygon (with "duplicate" coords removed), if it doesn't fail. Using the default XY Resolution for 4326 probably generates something like 0.000000000074289549 degrees, but what's eight orders of magnitude between friends? – Vince Aug 30 '18 at 14:47
  • @Hornbydd it's a standalone Python script, so if we need to adjust environment settings it has to be done in there. (There's no arcpy.env anything ... yet.) – Erica Aug 30 '18 at 14:50
  • @Vince I would have always set spatial reference out of a matter of habit but it's interesting to know ArcGIS tries to guess one. 8 orders between friends is barely a scratch! :) – Hornbydd Aug 30 '18 at 15:02
  • So it's only five orders at 10.5.1, though I think it was higher back at 10.2. – Vince Aug 30 '18 at 15:22
4

It's always a mistake to not specify a SpatialReference when creating a geometry. The reason is that a SpatialReference is required, and if you don't provide a proper one, ArcGIS will provide an improper one.

Using Desktop 10.5.1, the default XY Resolution is 0.0001 units, which produces a generalized polygon (with "duplicate" coordinates removed), if it doesn't fail. When you create a SpatialReference using an srid of 4326 (GCS_WGS_1984), the default XY Resolution changes to 0.000000001 degrees (it may have been smaller back at 10.2), which is nearly always overkill (~= 0.1 millimeter) and often needlessly increases storage requirements (by as much as 80%, vice SpatialReference.setFalseOriginAndUnits(-400,-400,10000000) ~= 1cm resolution; your mileage may vary)

In comparing the 95 input points to 11 output using the default spatial reference, I'd expect you'd see that coordinate values which differ by less than the polygonObj.spatialReference.XYResolution are removed as duplicates.

It's not possible to determine why more points are populated once the object is converted to a Polygon geometry without knowing the exact coordinate values used. But the Polygon object can sometimes work quite hard to force a vertex stream into a valid polygon, correcting overlaps and crossing lines by generating holes and additional parts. I'd suggest you also query polygonObj.partCount and/or extract the WKT or JSON of the resulting shape.

The definitive work on how SpatialReference operates is Understanding Coordinate Management in the Geodatabase which goes into the math used in geometry objects.

  • 1
    The more we look at it (actually looking by putting it on a map, lol) the more it's clear that poorly ordered vertices are causing the drastic increase in point count. Thank you for the thorough answer, it really helped me think through it and explain all this to my junior developer :) – Erica Aug 30 '18 at 21:24
  • 1
    Yeah, the ordered part of "ordered list of coordinates" is key in the definition of a polygon. If order has been lost, you can salvage something with a multipart PointGeometry and the convexHull() request, but that won't work well with convex shapes. – Vince Aug 31 '18 at 0:30
  • Err, concave shapes. Doh. – Vince Sep 2 '18 at 3:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.