Skip to content

Bug - shape.JSON property rings different from shape.WKT rings #5

@sf-apex

Description

@sf-apex

Hello! I briefly chatted with two of you at the expo in Palm Springs last week, and thought I'd give this new repo's issues section a try...

Describe the bug
I'm sending some polygon data (as JSON) to a vendor's API, and finding some differences in the coordinate structure when using the .JSON property vs the .WKT property of the arcpy.Geometry object. I suspect this might be a bug within the .JSON property, although is also very niche and may lead to some other resolution.

The difference only occurs for polygons with a self-intersection, e.g.,:

Image

To Reproduce
Please provide steps or code to reproduce the behavior

  1. I'm on ArcGIS Pro 3.2 / Python 3.9
  2. A simple shapefile (with a self-intersection) is here: example.zip
  3. A difference can be seen by getting the geometry object, calling .JSON and .WKT, and comparing the results.
  4. The code below includes a string replacement hack I'm using (as a stand-in, getting the desired json from the wkt), and makes this difference a little clearer.
import arcpy
import json


def wkt_to_json(wkt: str):
    """
    Janky text replacement to mimic getting arcpy.Geometry.JSON from wkt

    Args:
        wkt (str): well known text

    Returns:
        str: coords as lists of lists, etc
    """
    return wkt.replace(
        "MULTIPOLYGON (((", "[[[["
    ). replace(
        ")))", "]]]]"
    ).replace(
        ")), ((", "]]],[[["
    ).replace(
        "), (", "]],[["
    ).replace(
        ", ", "],["
    ).replace(
        " ", ","
    )


if __name__ == "__main__":

    # define shp
    shp_path = r"c:\_test\example.shp"

    # get shape object in wgs 84
    shape = arcpy.da.SearchCursor(
        in_table = shp_path,
        field_names = ["shape@"],
        spatial_reference = arcpy.SpatialReference(4326)
    ).next()[0]

    # get coord rings from json
    rings_json = [json.loads(shape.JSON)["rings"]]

    # get coord rings from wkt
    rings_wkt = eval(wkt_to_json(shape.WKT))

    # print results
    print(f"\njson:\n{rings_json}\n\nwkt:\n{rings_wkt}\n")

Results in the following print message (notice the extra nesting level in the WKT):

json:
[[[[-102.63360131351193, 39.178121928426435], [-102.62342030125676, 39.17815377092889], [-102.63297793390872, 39.17073880963662], [-102.63360131351193, 39.178121928426435]], [[-102.63360131351193, 39.178121928426435], [-102.64149801399176, 39.17802302383014], [-102.63366335417479, 39.18350071170985], [-102.63360131351193, 39.178121928426435]]]]

wkt:
[[[[-102.63360131351193, 39.178121928426435], [-102.63297793390872, 39.17073880963662], [-102.62342030125676, 39.17815377092889], [-102.63360131351193, 39.178121928426435]]], [[[-102.63360131351193, 39.178121928426435], [-102.63366335417479, 39.18350071170985], [-102.64149801399176, 39.17802302383014], [-102.63360131351193, 39.178121928426435]]]]

Expected behavior

I'd like to be able to use the .JSON method, since it's more concise and seems to work fine for all other polygons (without a self-intersection).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions