Why does the WKT object returned by arcgis.geometry.Geometry.WKT not emulate OGC WKT?

3356
6
Jump to solution
11-08-2018 01:01 AM
Lakshmi_KanthanMuralikrishnan
New Contributor III

Hi all,

The issue is this:

While the WKT attribute of an arcgis.geometry.Geometry object returns me WKT geometry in this format: (for instance)

MULTIPOLYGON (((30, 20), (45, 40), (10, 40), (30, 20)),((15, 5), (40, 10), (10, 20), (5, 10), (15, 5)))‍‍‍

An OGC WKT string for the same geometry would look so:

MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))‍

This, in my opinion, diminishes the usability of the WKT object. For instance, if I want to write this to a database in the database's native geometry data type, I cannot use methods that convert WKT to Geometry (like STAsText in MS SQL Server), as they will be expecting the data to be in OGC WKT format.

The questions are, hence,

- why does the arcgis.geometry.Geometry.WKT object not have the format specified in OGC specification for WKT representation?

- will this behaviour be changed, at all, to conform to the said standards in the future releases of ArcGIS API for Python?

0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

The ArcGIS API for Python supports using ArcPy and Shapely geometry libraries, as well as neither of those.  Sometimes, usually a bug, code generates different outputs when different geometry libraries are being used.

I was able to replicate your issue using a clean Anaconda distribution with just ArcGIS API for Python installed, no ArcPy nor Shapely.

>>> print(geom.type)
Polygon
>>>
>>> print(geom.WKT[:120])
MULTIPOLYGON (((-120.5001609997531204,  38.0041239997223812), (-120.5002550003627562,  38.0050989999908424), (-120.50044
>>> ‍‍‍‍‍‍‍‍‍‍‍‍

When Shapely is installed, the results are correct like when ArcPy is installed.

>>>
>>> print(geom.type)
Polygon
>>>
>>> print(geom.WKT[:120])
MULTIPOLYGON (((-120.5001609997531 38.00412399972238, -120.5002550003628 38.00509899999084, -120.5004410001356 38.006630
>>>

View solution in original post

6 Replies
JoshuaBixby
MVP Esteemed Contributor

Using one of the examples in Esri's documentation for arcgis.geometry module — arcgis 1.5.0 documentation :

>>> import arcgis
>>> print(arcgis.__version__)
1.5.0
>>>
>>> from arcgis.geometry import Geometry
>>> geom = Geometry({
...   "rings" : [[[-97.06138,32.837],[-97.06133,32.836],[-97.06124,32.834],[-97.06127,32.832],
...               [-97.06138,32.837]],[[-97.06326,32.759],[-97.06298,32.755],[-97.06153,32.749],
...               [-97.06326,32.759]]],
...   "spatialReference" : {"wkid" : 4326}
... })
>>> print (geom.type) # Polygon
Polygon
>>>
>>> print(geom.WKT)
MULTIPOLYGON (((-97.06138 32.837000000000003, -97.061269999999993 32.832000000000001, -97.061239999999998 32.834000000000003, -97.061329999999998 32.835999999999999, -97.06138 32.837000000000003), (-97.06326 32.759, -97.061530000000005 32.749000000000002, -97.062979999999996 32.755000000000003, -97.06326 32.759)))
>>>

At least in this example, the WKT output format is correct.  Can you provide more information about where your geometry object is coming from?

0 Kudos
Lakshmi_KanthanMuralikrishnan
New Contributor III

Hi Joshua Bixby

Thanks for your response!

The geometry object I got is a response from the TIGERWeb API (follow it here: URL). 

These are the steps I followed:

- query the REST API (using arcgis.features.FeatureLayer.query method) to get a arcgis.features.FeatureSet object.

- get the geometry dict from each feature in the FeatureSet object and append the spatialReference key to the dictionary

- pass this geometry dict object to the arcgis.geometry.Geometry class to create a Geometry object instance

- Use the associated WKT attribute to retrieve the WKT string representation.

This is my python script:

from arcgis.features import FeatureLayer
from arcgis.geometry import Geometry

# API URL
api_url = 'https://tigerweb.geo.census.gov/arcgis/rest/services/TIGERweb/State_County/MapServer/19'

# I used Web Mercator Auxiliary PCS
# although the format of the resulting WKT string
# is the same for 4326
wkid = 4326

fl = FeatureLayer(api_url)

# Take a sample set of OIDs
oid_list = [1, 2, 3]

# query the feature later
fs = fl.query(
    out_sr=wkid,
    object_ids=','.join(map(str, oid_list)),
    out_fields='*'
)

sample_feature = fs.features[0]

# geometry dict for a single feature
geom_dict = sample_feature.geometry
geom_dict.update({"spatialReference": {"wkid": wkid}})

print(geom_dict)
# This should look like:
# {'rings': [[...]],  'spatialReference': {'wkid': 3857}}

geom = Geometry(geom_dict)

print(geom.type)
# Polygon

print(geom.WKT)
# MULTIPOLYGON (((-120.5001609997531204,  38.0041239997223812), ..., (-120.5001609997531204,  38.0041239997223812)))
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I do follow what is specified in the documentation, and still end up with a different result. Can you run this script in your environment and see if you can reproduce the error?

N.B.:

- The FeatureServer resource is not secured. So, you don't need any access token.

- The version of arcgis in my environment is, indeed, 1.5.0.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

This is what I get for the last two prints statements using your code (WKT is truncated but there is enough to see format😞

>>> print(geom.type)
Polygon
>>>
>>> print(geom.WKT[:120])
MULTIPOLYGON (((-120.50016099975312 38.004123999722381, -120.50006299984382 38.003133999851144, -120.49986200000237 38.0
>>>

The formatting is correct on my system.  I am running 1.5.0 as well.  Are you running it with a bundled Pro installation or on its own?

0 Kudos
Lakshmi_KanthanMuralikrishnan
New Contributor III

No I am not using the arcgis that comes with Pro. I am using the conda installation of arcgis api for python. But, why would the specification of WKT vary, irrespective of using the API with Pro or not?

Anyway, I'll try with the arcgis package in Pro and update here.

Thank You!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

The ArcGIS API for Python supports using ArcPy and Shapely geometry libraries, as well as neither of those.  Sometimes, usually a bug, code generates different outputs when different geometry libraries are being used.

I was able to replicate your issue using a clean Anaconda distribution with just ArcGIS API for Python installed, no ArcPy nor Shapely.

>>> print(geom.type)
Polygon
>>>
>>> print(geom.WKT[:120])
MULTIPOLYGON (((-120.5001609997531204,  38.0041239997223812), (-120.5002550003627562,  38.0050989999908424), (-120.50044
>>> ‍‍‍‍‍‍‍‍‍‍‍‍

When Shapely is installed, the results are correct like when ArcPy is installed.

>>>
>>> print(geom.type)
Polygon
>>>
>>> print(geom.WKT[:120])
MULTIPOLYGON (((-120.5001609997531 38.00412399972238, -120.5002550003628 38.00509899999084, -120.5004410001356 38.006630
>>>
Lakshmi_KanthanMuralikrishnan
New Contributor III

It does work with Shapely or arcpy, yeah. For now, I am just using Python's re to modify the WKT I am getting to the OGC WKT specification.

I may probably end up using arcpy for different reasons in the same environment. So, I think this issue should inherently not appear then.

Thank You for your assistance in this regard!

0 Kudos