POST
|
That worked perfectly, Randy. I attached a screen capture to show you how the points appear after the code is executed. They are all more or less inside the polygons. I can go around to each polygon and relocate those points that fell outside their respective boundary. Thank you again for all your hard work! I really appreciate your assistance and this will go along way to helping us better manage our cemetery plots. With Veterans Day coming up it couldn't have come at a better time. Jeff
... View more
10-29-2020
12:39 PM
|
0
|
0
|
1953
|
POST
|
Hi Randy, Thank you again for your assistance. I ran the above code and received the following error message: Executing: OccupantPtsEnhanced Start Time: Thu Oct 29 06:38:15 2020 Running script OccupantPtsEnhanced... Failed script OccupantPtsEnhanced... Traceback (most recent call last): File "R:\Jeff\City_Projects\Cemetery\OccupantPtsEnhanced.py", line 86, in <module> sortedList = sorted(relateDict[labelKey]) TypeError: can't compare datetime.datetime to NoneType Failed to execute (OccupantPtsEnhanced). Failed at Thu Oct 29 06:38:21 2020 (Elapsed Time: 5.61 seconds) Hopefully this will make some sense to you. Thanks. Jeff
... View more
10-29-2020
03:43 AM
|
0
|
2
|
1953
|
POST
|
Here is the latest "original" code that I have from you if that helps. I commented out the sections we discussed earlier but everything else is the same...minus the fields I have tried to add to no avail. import arcpy # if not in python window
import os
# Prep work : set up some parameters
# feature with geometry - specifically polygons
fc = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy"
# related table with data
relateFC = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\DBOPlotOccJoin"
relateFieldsList = ["UserField4", "Name"] # Born and Died are optional, others can be added
# new point feature we will create
outPath = r'R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb'
outName = 'AGO_cemetery'
outFields = ['SHAPE@X', 'SHAPE@Y', 'Cemetery', 'Plot', 'Name']
# full path to new feature
outFC = os.path.join(outPath, outName)
# Step 1 : create a new feature
# spatial reference for new feature
sr = arcpy.Describe(fc).SpatialReference # same spatial reference as source feature
# create the new feature
arcpy.CreateFeatureclass_management(out_path = outPath, out_name = outName, geometry_type = "POINT",
template = "#", has_m = "DISABLED", has_z = "DISABLED",
spatial_reference = sr)
# create fields (all text): Cemetery, Plot, Name, Born, Died
arcpy.AddField_management(in_table = outFC, field_name = 'Cemetery',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Cemetery", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'Plot',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Plot", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'Name',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Name", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
#arcpy.AddField_management(in_table = outFC, field_name = 'BirthDate',
#field_type = "STRING", field_precision = "#", field_scale = "#",
#field_length = 20, field_alias = "BirthDate", field_is_nullable = "NULLABLE",
#field_is_required = "NON_REQUIRED", field_domain = "#")
#arcpy.AddField_management(in_table = outFC, field_name = 'DeathDate',
#field_type = "STRING", field_precision = "#", field_scale = "#",
#field_length = 20, field_alias = "DeathDate", field_is_nullable = "NULLABLE",
#field_is_required = "NON_REQUIRED", field_domain = "#")
# Step 2 : build the related dictionary
relateDict = {}
# read the related table's data into a dictionary
# the key will be the first field in the relateFieldsList
# the value will be a list of tuples starting with the second field in the relatedFields list and using index [0]
with arcpy.da.SearchCursor(relateFC, relateFieldsList) as relateRows:
for relateRow in relateRows:
relateKey = relateRow[0]
if not relateKey in relateDict:
relateDict[relateKey] = [relateRow[1:]]
else:
relateDict[relateKey].append(relateRow[1:])
del relateRows, relateRow # clean up
# Step 3 : populate the new feature
# ready an insert cursor and loop through source feature and dictionary
insertCursor = arcpy.da.InsertCursor(outFC, outFields)
with arcpy.da.SearchCursor(fc,['SHAPE@', 'Cemetery', 'GIS_ID']) as cursor:
for row in cursor:
labelKey = row[2] # the link
if labelKey in relateDict:
sortedList = sorted(relateDict[labelKey])
listCount = len(sortedList)
# calculate values for point geometry
xstep = (row[0].extent.XMax - row[0].extent.XMin)/listCount
ystep = (row[0].extent.YMax - row[0].extent.YMin)/listCount
xmin = row[0].extent.XMin + (xstep/2) # x coord for first point
ymin = row[0].extent.YMin + (ystep/2) # y coord for first point
# final data
for fieldValues in sortedList:
name = fieldValues[0]
# assuming the dates are type text/string and not type date
# otherwise some conversion will be required
#born = fieldValues[1]
#died = fieldValues[2]
# print(xmin, ymin, row[1], labelKey, name) # if printing, remove: born, died
insertCursor.insertRow([xmin, ymin, row[1], labelKey, name])# remove: born, died
xmin += xstep # add step to x coord
ymin += ystep # add step to y coord
else: # not in dictionary
pass # substitute with error code if necessary
del insertCursor Also, I repaired the geometry issues and ran the above code and everything came through including our other cemetery. It works great. Thank you. I've tried adding the additional fields that I mentioned in my previous inquiry but it refuses to carry them over. Hopefully you will be able to once again enlighten me.
... View more
10-28-2020
12:41 PM
|
0
|
4
|
1953
|
POST
|
That would be great, Randy. The Vettxt is actually a text field. It was numeric as another field but I converted it to text. The OccLoc field is text and is just a tidier version with better dashes. The BirthDate and DeathDate fields are dates at present. It appears they had more luck recording the death dates than the birth dates. A few null values in the birth dates. Thanks again, Jeff
... View more
10-27-2020
02:29 PM
|
0
|
0
|
1953
|
POST
|
I do have a couple follow-up questions...I'd like to add additional field outputs beyond Cemetery, Plot and Name. I've created two additional fields in DBOPlotOccJoin; one called Vettxt (text field featuring binary 0 or 1, Vet or not) and the other called OccLoc (featuring the entire Cemetery-Block-Lot-Plot as text). I have tried a few things that seemed "logical" of where to place these to be added as output fields but they don't seem to come over after the code is run. If I want them added along with Cemetery, Plot and Name, where should they go in the code? Also, I would like to add BirthDate and DeathDate. Do I need to convert them to text or just change string to date and modify the Born and Died call outs?
... View more
10-27-2020
01:05 PM
|
0
|
0
|
1953
|
POST
|
No. There was no message of an error. I checked the geometry and it appears I have 12 issues; 9 self intersections and 3 null geometry.
... View more
10-27-2020
12:57 PM
|
0
|
0
|
1963
|
POST
|
Yes. It was definitely getting confused. I made the modifications and am no longer getting the indent error but this error has arisen: Traceback (most recent call last): File "R:\Jeff\City_Projects\Cemetery\OccupantPtsRev2.py", line 81, in <module> xstep = (row[0].extent.XMax - row[0].extent.XMin)/listCount AttributeError: 'NoneType' object has no attribute 'extent' Error corresponds to line 13 in the above you provided.
... View more
10-27-2020
11:49 AM
|
0
|
3
|
2003
|
POST
|
I received the following error message... Executing: OccupantPtsRev2 Start Time: Tue Oct 27 13:53:02 2020 Running script OccupantPtsRev2... Failed script OccupantPtsRev2... IndentationError: unexpected indent (OccupantPtsRev2.py, line 79) Failed to execute (OccupantPtsRev2). Failed at Tue Oct 27 13:53:02 2020 (Elapsed Time: 0.02 seconds) Line 79 (11 in above example) is where I inserted "if row[0] is None:" following your above indentation example.
... View more
10-27-2020
10:59 AM
|
0
|
5
|
2003
|
POST
|
Could you provide a snapshot of how the code should look for Step 3? I'm a little confused as to where the above code should be placed and the correct indentation.
... View more
10-27-2020
10:33 AM
|
0
|
7
|
2003
|
POST
|
With the error message coming up I didn't think to check if a point feature class was still created. Doh! I've attached a screen capture of the attribute table for AGO_cemetery. We actually have two cemeteries; Oak Lawn and Memorial Gardens. The attribute table only illustrates Oak Lawn even though the polygons for both cemeteries are included within the same feature class; BSACemeteriesCopy. Could that be the issue regarding the "extent" error message?
... View more
10-27-2020
04:43 AM
|
0
|
9
|
2003
|
POST
|
Hi Randy, Yes. BSACemeteriesCopy is a polygon feature class. Jeff
... View more
10-26-2020
02:38 PM
|
0
|
0
|
2003
|
POST
|
import arcpy # if not in python window
import os
# Prep work : set up some parameters
# feature with geometry - specifically polygons
fc = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy"
# related table with data
relateFC = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\DBOPlotOccJoin"
relateFieldsList = ["UserField4", "Name"] # Born and Died are optional, others can be added
# new point feature we will create
outPath = r'R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb'
outName = 'AGO_cemetery'
outFields = ['SHAPE@X', 'SHAPE@Y', 'Cemetery', 'Plot', 'Name']
# full path to new feature
outFC = os.path.join(outPath, outName)
# Step 1 : create a new feature
# spatial reference for new feature
sr = arcpy.Describe(fc).SpatialReference # same spatial reference as source feature
# create the new feature
arcpy.CreateFeatureclass_management(out_path = outPath, out_name = outName, geometry_type = "POINT",
template = "#", has_m = "DISABLED", has_z = "DISABLED",
spatial_reference = sr)
# create fields (all text): Cemetery, Plot, Name, Born, Died
arcpy.AddField_management(in_table = outFC, field_name = 'Cemetery',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Cemetery", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'Plot',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Plot", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'Name',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "Name", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
#arcpy.AddField_management(in_table = outFC, field_name = 'BirthDate',
#field_type = "STRING", field_precision = "#", field_scale = "#",
#field_length = 20, field_alias = "BirthDate", field_is_nullable = "NULLABLE",
#field_is_required = "NON_REQUIRED", field_domain = "#")
#arcpy.AddField_management(in_table = outFC, field_name = 'DeathDate',
#field_type = "STRING", field_precision = "#", field_scale = "#",
#field_length = 20, field_alias = "DeathDate", field_is_nullable = "NULLABLE",
#field_is_required = "NON_REQUIRED", field_domain = "#")
# Step 2 : build the related dictionary
relateDict = {}
# read the related table's data into a dictionary
# the key will be the first field in the relateFieldsList
# the value will be a list of tuples starting with the second field in the relatedFields list and using index [0]
with arcpy.da.SearchCursor(relateFC, relateFieldsList) as relateRows:
for relateRow in relateRows:
relateKey = relateRow[0]
if not relateKey in relateDict:
relateDict[relateKey] = [relateRow[1:]]
else:
relateDict[relateKey].append(relateRow[1:])
del relateRows, relateRow # clean up
# Step 3 : populate the new feature
# ready an insert cursor and loop through source feature and dictionary
insertCursor = arcpy.da.InsertCursor(outFC, outFields)
with arcpy.da.SearchCursor(fc,['SHAPE@', 'Cemetery', 'GIS_ID']) as cursor:
for row in cursor:
labelKey = row[2] # the link
if labelKey in relateDict:
sortedList = sorted(relateDict[labelKey])
listCount = len(sortedList)
# calculate values for point geometry
xstep = (row[0].extent.XMax - row[0].extent.XMin)/listCount
ystep = (row[0].extent.YMax - row[0].extent.YMin)/listCount
xmin = row[0].extent.XMin + (xstep/2) # x coord for first point
ymin = row[0].extent.YMin + (ystep/2) # y coord for first point
# final data
for fieldValues in sortedList:
name = fieldValues[0]
# assuming the dates are type text/string and not type date
# otherwise some conversion will be required
#born = fieldValues[1]
#died = fieldValues[2]
# print(xmin, ymin, row[1], labelKey, name) # if printing, remove: born, died
insertCursor.insertRow([xmin, ymin, row[1], labelKey, name])# remove: born, died
xmin += xstep # add step to x coord
ymin += ystep # add step to y coord
else: # not in dictionary
pass # substitute with error code if necessary
del insertCursor Apologies Randy...here is the code with the syntax highlighter applied. Jeff
... View more
10-26-2020
12:01 PM
|
0
|
0
|
1975
|
POST
|
Hi Randy, Thank you for responding to my question. I made the commenting out modifications you indicated and received a different error this time. " no attribute 'extent' Here is the code in case you need to see it again... Thanks again. Jeff import arcpy # if not in python window import os # Prep work : set up some parameters # feature with geometry - specifically polygons fc = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy" # related table with data relateFC = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\DBOPlotOccJoin" relateFieldsList = ["UserField4", "Name"] # Born and Died are optional, others can be added # new point feature we will create outPath = r'R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb' outName = 'AGO_cemetery' outFields = ['SHAPE@X', 'SHAPE@Y', 'Cemetery', 'Plot', 'Name'] # full path to new feature outFC = os.path.join(outPath, outName) # Step 1 : create a new feature # spatial reference for new feature sr = arcpy.Describe(fc).SpatialReference # same spatial reference as source feature # create the new feature arcpy.CreateFeatureclass_management(out_path = outPath, out_name = outName, geometry_type = "POINT", template = "#", has_m = "DISABLED", has_z = "DISABLED", spatial_reference = sr) # create fields (all text): Cemetery, Plot, Name, Born, Died arcpy.AddField_management(in_table = outFC, field_name = 'Cemetery', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Cemetery", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") arcpy.AddField_management(in_table = outFC, field_name = 'Plot', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Plot", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") arcpy.AddField_management(in_table = outFC, field_name = 'Name', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Name", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") #arcpy.AddField_management(in_table = outFC, field_name = 'BirthDate', #field_type = "STRING", field_precision = "#", field_scale = "#", #field_length = 20, field_alias = "BirthDate", field_is_nullable = "NULLABLE", #field_is_required = "NON_REQUIRED", field_domain = "#") #arcpy.AddField_management(in_table = outFC, field_name = 'DeathDate', #field_type = "STRING", field_precision = "#", field_scale = "#", #field_length = 20, field_alias = "DeathDate", field_is_nullable = "NULLABLE", #field_is_required = "NON_REQUIRED", field_domain = "#") # Step 2 : build the related dictionary relateDict = {} # read the related table's data into a dictionary # the key will be the first field in the relateFieldsList # the value will be a list of tuples starting with the second field in the relatedFields list and using index [0] with arcpy.da.SearchCursor(relateFC, relateFieldsList) as relateRows: for relateRow in relateRows: relateKey = relateRow[0] if not relateKey in relateDict: relateDict[relateKey] = [relateRow[1:]] else: relateDict[relateKey].append(relateRow[1:]) del relateRows, relateRow # clean up # Step 3 : populate the new feature # ready an insert cursor and loop through source feature and dictionary insertCursor = arcpy.da.InsertCursor(outFC, outFields) with arcpy.da.SearchCursor(fc,['SHAPE@', 'Cemetery', 'GIS_ID']) as cursor: for row in cursor: labelKey = row[2] # the link if labelKey in relateDict: sortedList = sorted(relateDict[labelKey]) listCount = len(sortedList) # calculate values for point geometry xstep = (row[0].extent.XMax - row[0].extent.XMin)/listCount ystep = (row[0].extent.YMax - row[0].extent.YMin)/listCount xmin = row[0].extent.XMin + (xstep/2) # x coord for first point ymin = row[0].extent.YMin + (ystep/2) # y coord for first point # final data for fieldValues in sortedList: name = fieldValues[0] # assuming the dates are type text/string and not type date # otherwise some conversion will be required #born = fieldValues[1] #died = fieldValues[2] # print(xmin, ymin, row[1], labelKey, name) # if printing, remove: born, died insertCursor.insertRow([xmin, ymin, row[1], labelKey, name])# remove: born, died xmin += xstep # add step to x coord ymin += ystep # add step to y coord else: # not in dictionary pass # substitute with error code if necessary del insertCursor
... View more
10-26-2020
11:55 AM
|
0
|
12
|
1962
|
POST
|
Hi Randy, I received the following error message when I attempted to run the script..."Index error: tuple index out of range". Here is the code with some changes that I made...commenting out...etc.. Can you please take a look and see where I might have gone wrong? Thanks. Jeff import arcpy # if not in python window import os # Prep work : set up some parameters # feature with geometry - specifically polygons fc = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy" # related table with data relateFC = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\DBOPlotOccJoin" relateFieldsList = ["UserField4", "Name"] # Born and Died are optional, others can be added # new point feature we will create outPath = r'R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb' outName = 'AGO_cemetery' outFields = ['SHAPE@X', 'SHAPE@Y', 'Cemetery', 'Plot', 'Name'] # full path to new feature outFC = os.path.join(outPath, outName) # Step 1 : create a new feature # spatial reference for new feature sr = arcpy.Describe(fc).SpatialReference # same spatial reference as source feature # create the new feature arcpy.CreateFeatureclass_management(out_path = outPath, out_name = outName, geometry_type = "POINT", template = "#", has_m = "DISABLED", has_z = "DISABLED", spatial_reference = sr) # create fields (all text): Cemetery, Plot, Name, Born, Died arcpy.AddField_management(in_table = outFC, field_name = 'Cemetery', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Cemetery", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") arcpy.AddField_management(in_table = outFC, field_name = 'Plot', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Plot", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") arcpy.AddField_management(in_table = outFC, field_name = 'Name', field_type = "STRING", field_precision = "#", field_scale = "#", field_length = 50, field_alias = "Name", field_is_nullable = "NULLABLE", field_is_required = "NON_REQUIRED", field_domain = "#") #arcpy.AddField_management(in_table = outFC, field_name = 'BirthDate', #field_type = "STRING", field_precision = "#", field_scale = "#", #field_length = 20, field_alias = "BirthDate", field_is_nullable = "NULLABLE", #field_is_required = "NON_REQUIRED", field_domain = "#") #arcpy.AddField_management(in_table = outFC, field_name = 'DeathDate', #field_type = "STRING", field_precision = "#", field_scale = "#", #field_length = 20, field_alias = "DeathDate", field_is_nullable = "NULLABLE", #field_is_required = "NON_REQUIRED", field_domain = "#") # Step 2 : build the related dictionary relateDict = {} # read the related table's data into a dictionary # the key will be the first field in the relateFieldsList # the value will be a list of tuples starting with the second field in the relatedFields list and using index [0] with arcpy.da.SearchCursor(relateFC, relateFieldsList) as relateRows: for relateRow in relateRows: relateKey = relateRow[0] if not relateKey in relateDict: relateDict[relateKey] = [relateRow[1:]] else: relateDict[relateKey].append(relateRow[1:]) del relateRows, relateRow # clean up # Step 3 : populate the new feature # ready an insert cursor and loop through source feature and dictionary insertCursor = arcpy.da.InsertCursor(outFC, outFields) with arcpy.da.SearchCursor(fc,['SHAPE@', 'Cemetery', 'GIS_ID']) as cursor: for row in cursor: labelKey = row[2] # the link if labelKey in relateDict: sortedList = sorted(relateDict[labelKey]) listCount = len(sortedList) # calculate values for point geometry xstep = (row[0].extent.XMax - row[0].extent.XMin)/listCount ystep = (row[0].extent.YMax - row[0].extent.YMin)/listCount xmin = row[0].extent.XMin + (xstep/2) # x coord for first point ymin = row[0].extent.YMin + (ystep/2) # y coord for first point # final data for fieldValues in sortedList: name = fieldValues[0] # assuming the dates are type text/string and not type date # otherwise some conversion will be required born = fieldValues[1] died = fieldValues[2] # print(xmin, ymin, row[1], labelKey, name, born, died) insertCursor.insertRow([xmin, ymin, row[1], labelKey, name, born, died]) xmin += xstep # add step to x coord ymin += ystep # add step to y coord else: # not in dictionary pass # substitute with error code if necessary del insertCursor
... View more
10-26-2020
08:59 AM
|
0
|
2
|
1975
|
POST
|
Thank you Randy for going to so much trouble and adding such incredible detail to your code. The directions you have supplied should be very helpful. So many times I encounter code through my cloud travels that leave a little too much for me to try and decipher and in the end it becomes a lost cause. I will attempt to implement and run it through some trials and report back. Again, many thanks Randy and have a great weekend! Jeff
... View more
10-23-2020
11:38 AM
|
0
|
0
|
1975
|
Title | Kudos | Posted |
---|---|---|
1 | 10-22-2020 09:17 AM | |
1 | 06-04-2020 03:46 AM | |
1 | 02-25-2020 10:16 AM | |
1 | 12-31-2019 03:49 AM | |
1 | 01-17-2019 07:30 AM |
Online Status |
Offline
|
Date Last Visited |
10-02-2023
08:46 AM
|