Utilizing 'fromWKT' function in python in version 10.1

8652
7
11-14-2012 09:28 AM
RyanWilliams1
New Contributor
I have a text file that includes a well known text type field representing polygons. I noticed version 10.1 has a python function that imports WKT to a geometry type (fromWKT). The help however does not include an example of how that function is used. Here is a test a entered into the python scripting window in ArcMap:

import arcpy

test = arcpy.FromWKT("POLYGON ((X Y,X Y,X Y,X Y,X Y))", "") >>>

It runs with no error, but how will I retrieve or view this result? Does syntax look correct?

I have many records in the text file from which I have to retrieve the WKT string for each polygon and run this function, so do I need to build this function into a record loop in order to finally get a single polygon feature class?
Thanks for the help. Ryan Williams
Tags (2)
0 Kudos
7 Replies
T__WayneWhitley
Frequent Contributor
Interesting function that I have not used yet... however, if you want to test 'viewing' the return, I suggest loading the geom object 'test' into a polygon fc.  In other words, the specified return in the help doc is in your case a polygon geometry object, and yes why not loop on your input text file with the python function returning the geom to an insert cursor Shape field on a polygon fc?

As an initial test try Copy Features to 'view' the results for you 'test' object, something like:

arcpy.CopyFeatures_management(test, "< enter path here to new fc >")

You should be able to view the 'new' single test object shape in your specified new fc.  Once you know that works, proceed with construction of the looping code.

EDIT:
To add a little 'meat' to what I was saying, see the help file sample code (excerpt included below) at the bottom of the page at the link given - looks like you can build the 'feature list' and copy features all at once to your feature class.  But instead of passing in an array of points to define the polygons, you should be able to pass in the objects themselves fromWKT (since they're then already polygon objects).

http://resources.arcgis.com/en/help/main/10.1/index.html#//018z00000061000000


# Append to the list of Polygon objects
#
featureList.append(polygon)

# Create a copy of the Polygon objects, by using featureList as input to
#  the CopyFeatures tool.
#
arcpy.CopyFeatures_management(featureList, "c:/geometry/polygons.shp")
0 Kudos
RyanWilliams1
New Contributor
Thanks for the idea Wayne.
0 Kudos
RyanWilliams1
New Contributor
Thanks again Wayne for the good ideas. They worked. Here is my final script:

# convert well known text to geometry, and compile shapes into a single feature class...
# 11/15/2012
import arcpy

File = "Y:\\Projects\\Ryan\\Analysis\\CNickerson\\OK\\OKraw.mdb\\OK_AgparcelsWKT"

# dimension the WKT string field and poly ID field...
# the field holding the WKT string...
field1 = "coord_1"
# the field holding the unique ID...
field2 = "fidfips"

# set up the empty list...
featureList = []

# iterate on table row...
cursor = arcpy.SearchCursor(File)
row = cursor.next()
while row:
    print (row.getValue(field2))
   
    WKT = row.getValue(field1)
    # this is the part that converts the WKT string to geometry...
    temp = arcpy.FromWKT(WKT, "")
    # append the current geometry to the list...
    featureList.append(temp)

    row = cursor.next()
   
# copy all geometries in the list to a feature class...
arcpy.CopyFeatures_management(featureList, "Y:\\Projects\\Ryan\\Analysis\\CNickerson\\OK\\AgParcelShapes.shp")   

# clean up...
del row, temp, WKT, File, field1, featureList, cursor
0 Kudos
T__WayneWhitley
Frequent Contributor
Good work, Ryan!  Thanks for posting back - I was really curious about that.


FYI, just for future reference, you should insert your code between code tags, CODE and /CODE, (with brackets) so your code above would look like:


# convert well known text to geometry, and compile shapes into a single feature class...
# 11/15/2012
import arcpy

File = "Y:\\Projects\\Ryan\\Analysis\\CNickerson\\OK\\OKraw.mdb\\OK_AgparcelsWKT"

# dimension the WKT string field and poly ID field...
# the field holding the WKT string...
field1 = "coord_1"
# the field holding the unique ID...
field2 = "fidfips"

# set up the empty list...
featureList = []

# iterate on table row...
cursor = arcpy.SearchCursor(File)
row = cursor.next()
while row:
     print (row.getValue(field2))

     WKT = row.getValue(field1)
     # this is the part that converts the WKT string to geometry...
     temp = arcpy.FromWKT(WKT, "")
     # append the current geometry to the list...
     featureList.append(temp)

     row = cursor.next()

# copy all geometries in the list to a feature class...
arcpy.CopyFeatures_management(featureList, "Y:\\Projects\\Ryan\\Analysis\\CNickerson\\OK\\AgParcelShapes.shp")

# clean up...
del row, temp, WKT, File, field1, featureList, cursor
0 Kudos
RyanFortier
New Contributor III

Hello,

I believe I am trying to do something similar here. I have an SQLite table with multiple files. One of the columns in the table is WKT. I would like to take the WKT from all the files within the table and populate the "SHAPE" field in a feature class. Any ideas?

Thanks

0 Kudos
KimOllivier
Regular Contributor II

Although you can use arcpy.FromWKT() there is a much more elegant token on arcpy.da.InsertCursor() than enables you to load a wkt text string straight into a featureclass.

Here is an example loading from a CSV file into a geodatabase with the geometry as a wkt string, but the same thing would apply for a sqlite database source if you iterated through the records. If you have upgraded the sqlite database to a spatialite database then you could convert the string wkt field into the geometry field, but there is a bug that crashes da.Update(row) on a geopackage at the moment (10.3 pre-release) but the da.InsertCursor(row) works ok. Of course it works normally if your target is a filegeodatabase.

def create_new(rcl):

    ''' create a new featureclass from scratch'''

    # arcpy.management.CreateFeatureclass(ws, rcl, template='rcl_changeset_template', spatial_reference=sr)

    arcpy.management.CreateFeatureclass(ws, rcl, 'POLYLINE', spatial_reference=sr)

    arcpy.management.AddField(rcl, 'FID', 'LONG') # actually not a long but a complex string

    arcpy.management.AddField(rcl, 'CHANGE', 'TEXT', field_length=16)

    arcpy.management.AddField(rcl, 'ID', 'LONG')

    arcpy.management.AddField(rcl, 'ALT_ID', 'LONG')

    arcpy.management.AddField(rcl, 'STATUS', 'TEXT', field_length=4)

    arcpy.management.AddField(rcl, 'NON_CADASTRAL_RD', 'TEXT', field_length=1)

    arcpy.management.AddField(rcl, 'AUDIT_ID', 'LONG')

    arcpy.management.AddField(rcl, 'SE_ROW_ID', 'LONG')

    desc = arcpy.Describe(rcl)

    print "target fc:", rcl, desc.shapeType, desc.spatialReference.name, desc.featureType

    # create a buffer list without objectid and shape_length and rename shape field to a token

    buf = [f.name.upper() for f in desc.fields]

    print "Desc fields in target:",buf

    buf.remove('OBJECTID')

    # buf.remove('SHAPE_LENGTH')

    buf[buf.index("SHAPE")] = 'SHAPE@WKT'

    # shape field in cursor name MUST be one of special tokens so use SHAPE@WKT

    dBuf = {f.upper():buf.index(f) for f in buf}

    print "dBuf:", dBuf

    # insert records into the featureclass

    # maybe for speed we could use arcpy.da.Editor for bulk commits?

    debug = False

    icur = arcpy.da.InsertCursor(rcl, buf) # shape called SHAPE@ or SHAPE@WKT

    with open(csv_file,'r') as f:

        reader = csv.reader(f)

        n = 0

        for row in reader:

            if reader.line_num == 1:

                print "header:", len(row),row

                rowCSV = [r.upper().replace('__','') for r in row] # get rid of double underscores in __change__

                print "CSV header:",rowCSV

                rowCSV[rowCSV.index("SHAPE")] = 'SHAPE@WKT'

                dCSV = {r.upper():rowCSV.index(r) for r in rowCSV}

                print "dCSV:", dCSV

                for f in dBuf.keys():

                    try:

                        print "Field: {} Buf {}, CSV {} ".format(f, dBuf, dCSV)

                    except:

                        print "Field name dictionaries do not match", f

                        sys.exit(1)

                print

                print '-------------------- BEGIN --------------------------'

            else:

                n+=1

                # fieldmapping by name dictionaries

                # initialise a new buffer

                feat = [None] * len(buf)

                for f in buf: # iterate over field names

                    # just poke shape straight into buffer field as a WKT string!

                    if row[dCSV]: # populate if not an empty data element, otherwise leave as null

                        if f == 'FID':

                            feat[dBuf] = int(row[dCSV].split('.')[-1])

                            # print f,feat[dBuf]

                        else:

                            feat[dBuf] = row[dCSV]

                icur.insertRow(feat)

    del icur

    deltaTime = datetime.datetime.now() - start

    print n,"Well Done", deltaTime

    return

0 Kudos
RyanFortier
New Contributor III

Thanks you for the reply. I will try and implement this into my current project. FOr myself, the feature classes are already created in a FileGDB. I would like to take the WKT field in my SQLite DB and map it to the shape field in the feature classes. I would then like to map 2 other fields from the DB to the feature classes. I will let you know how this works out.

0 Kudos