POST
|
I don't see where 'm' in line 11 has been defined. For line 8, try this: m = p.listMaps('Map')[0]
... View more
11-05-2020
05:53 PM
|
0
|
1
|
8482
|
POST
|
I'm not sure I completely understand what you are trying to accomplish. If the variables fc_list, max_construction_lists, and min_construction_lists are related, then I suggest you combine them into a dictionary. That way, you can use the feature name to access the min and max lists. It looks like you are trying to determine the max and min values of household income in a variety of features. But I don't see where you are keeping track of what feature has what max and min values. Again, I would use a dictionary for this purpose with the key coming from the fc_list. My thoughts... const_lists = {
'Atlanta': {'max': [394, 394, 674, 452, 708, 589, 139], 'min': [303, 303, 245, 253, 333, 152, 50]},
'Boston': {'max': [510, 510, 874, 586, 912, 763, 180], 'min': [392, 392, 318, 327, 532, 196, 65]} }
field_list = ["MEDIAN_HOUSEHOLD_INCOME_2018", "CONST_PRICE_PER_SF_CONDO", "CONST_PRICE_PER_SF_MULTIFAM",
"CONST_PRICE_PER_SF_OFFICE", "CONST_PRICE_PER_SF_RETAIL", "CONST_PRICE_PER_SF_HOTEL",
"CONST_PRICE_PER_SF_INDUSTRIAL", "CONST_PRICE_PER_SF_PARKING"]
fc_list = ['Atlanta', 'Boston']
mm_dict = {} # max, min dictionary
for fc in fc_list:
print("Processing feature class: {}".format(fc))
with arcpy.da.SearchCursor(fc, 'MEDIAN_HOUSEHOLD_INCOME_2018') as cursor:
max = max(cursor)[0]
cursor.reset()
min = min(cursor)[0]
# print(fc, max, min)
mm_dict[fc] = {'max': max, 'min' : min }
del cursor
del max
del min
# print(mm_dict)
for fc in fc_list: # iterate through each feature class
# limit rows selected/updated to min and max household income
where = "MEDIAN_HOUSEHOLD_INCOME_2018 in ({}, {})".format(mm_dict[fc]['min'], mm_dict[fc]['max'])
# print where
with arcpy.da.UpdateCursor(fc, field_list, where) as cursor:
for row in cursor: # iterate through each row
if row[0] == mm_dict[fc]['min']:
lists = const_lists[fc]['min']
else:
lists = const_lists[fc]['max']
# print(fc, row[0], lists)
row[1] = lists[0]
row[2] = lists[1]
row[3] = lists[2]
row[4] = lists[3]
row[5] = lists[4]
row[6] = lists[5]
row[7] = lists[6]
cursor.updateRow(row)
print("Done updating max/min construction costs in all cities") I'm not sure what version you are using (Pro or Desktop) so there may be some code tweaks need - again, if I understand your problem correctly. And you may wish to add some additional error checking. Do you only want to update the rows with the minimum and maximum income? Anyway, hope this helps.
... View more
11-04-2020
08:20 PM
|
1
|
0
|
2119
|
POST
|
For security reasons, you would not want the username and password appended to the URL and sent unsecured as is the case for a get request. Look in your documentation on how to generate a post request. For reference: HTTP Methods GET vs POST
... View more
11-02-2020
12:48 PM
|
1
|
0
|
1802
|
POST
|
You button would need to trigger an HTTP post request. Code for python would be something like: # URL address of feature, similar to:
URL = "https://services.arcgis.com/<abcdef>/arcgis/rest/services/<layer>/FeatureServer/0/query"
dataFlds = ["FldOne", "FldTwo"]
query_dict = {
"where" : "EditDate >= DATE '{}'".format(editDate),
"outFields" : ",".join(dataFlds),
"orderByFields" : "EditDate",
"returnGeometry" : "true",
"outSR" : "4326", # lon, lat
"f": "json", "token": token['token'] }
r = requests.post(url = URL, data = query_dict)
returnJson = json.loads(r.content) Look at the HTML source of the page in your picture and you can see the names of the various form elements. In addition to the where query, looks like you will also need to set "f" to the return format you desire and probably include a token.
... View more
11-02-2020
12:54 AM
|
3
|
2
|
2651
|
POST
|
The sorted function is trying to sort the relateDict by all fields. Since some of the dates are null values, the function can't determine which should come first. You can either leave it unsorted or sort it only by the first element which is the name. # Replace the line:
sortedList = sorted(relateDict[labelKey])
# With this to leave unsorted:
sortedList = relateDict[labelKey]
# Or with this to sort only by first element (name) by using the key parameter:
sortedList = sorted(relateDict[labelKey], key=lambda x: x[0]) I would suggest leaving unsorted for now; use line 5.
... View more
10-29-2020
12:17 PM
|
2
|
1
|
1916
|
POST
|
The polygon is has 4 ring parts, and your code is requesting a centroid for each ring part. The first ring part has 3 pairs of coordinates: {
"geometry": {
"rings": [
[
[-9047616.7071, 3297677.1092999987],
[-9047617.2766, 3297676.960099999],
[-9047616.7071, 3297677.1092999987]
],
[
[-9047712.4177, 3297707.5879999995],
I'm not sure if the geometry is formed correctly, but I modified your code and ran the following in ArcMap's python window (10.5). I then converted the rings into geojson and created a polygon feature to get the coordinates of its centroid. >>> for i in inputJSON['geometry']['rings']:
... coordinates = i
... try:
... polygon = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in coordinates]), inSr)
... pcent = arcpy.Point
... pcent = polygon.centroid #error occurs here
... print(pcent.X, pcent.Y)
... except:
... print("bad ring")
...
bad ring
(-9047688.632686786, 3297747.352303187)
(-9047607.857266191, 3297958.89263077)
(-9047509.45395274, 3297862.9346273225)
>>>
>>> coordinates = inputJSON['geometry']['rings']
... geojson_polygon = {"type": "Polygon", "coordinates" : coordinates }
... polygon = arcpy.AsShape(geojson_polygon)
...
... pcent = arcpy.Point
... pcent = polygon.centroid
...
... print pcent.X, pcent.Y
...
-9047510.96964 3297863.03471
If the polygon has only one ring, you may get the correct centroid. If it has multiple parts, you may be getting only the centroid of the first part.
... View more
10-28-2020
08:00 PM
|
2
|
1
|
4858
|
POST
|
Here's some code to try: import arcpy # if not in python window
import os
# set up variables
# 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", "BirthDate", "DeathDate", "Vettxt", "OccLoc"]
# new point feature we will create
outPath = r'C:\Users\Randy\Documents\ArcGIS\PythonScripts\fairhurst\fairhurst.gdb'
outName = 'AGO_cemetery'
outFields = ['SHAPE@X', 'SHAPE@Y', 'Cemetery', 'Plot', 'Name', 'BirthDate', 'DeathDate', 'Vettxt', 'OccLoc']
# 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: Cemetery, Plot, Name, BirthDate, DeathDate, Vettxt, OccLoc
# modify the size of text fields as required
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 = "DATE", field_precision = "#", field_scale = "#",
field_length = "#", 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 = "DATE", field_precision = "#", field_scale = "#",
field_length = "#", field_alias = "DeathDate", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'Vettxt',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 1, field_alias = "Vettxt", field_is_nullable = "NULLABLE",
field_is_required = "NON_REQUIRED", field_domain = "#")
arcpy.AddField_management(in_table = outFC, field_name = 'OccLoc',
field_type = "STRING", field_precision = "#", field_scale = "#",
field_length = 50, field_alias = "OccLoc", 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
cemetery = row[1] # cemetery name
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:
# field values from related table : add additional processing if necessary
name = fieldValues[0]
born = fieldValues[1]
died = fieldValues[2]
vet = fieldValues[3]
occloc = fieldValues[4]
# print(xmin, ymin, cemetery, labelKey, name, born, died, vet, occloc)
insertCursor.insertRow([xmin, ymin, cemetery, labelKey, name, born, died, vet, occloc])
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 In line 10 and line 15, the birth/death, veteran, and location fields have been added to the list of field names. In Step 1 (lines 20-58), additions have been made to the fields for the output feature. Suggestions to think about, after testing the code: Since this is going to AGO, you may wish to rename the fields to something that may make more sense to the user - or at least change the alias to something more meaningful. If you rename fields you will need to make the appropriate changes to lines 10 an 15. The Vettxt being a 1 or 0 may not make sense to the end user. A true/false a Y/N may make more sense. Lines 96-102 have been modified to include the new fields. Other than that, I think the remaining code is mostly the same. Hope this helps.
... View more
10-28-2020
12:57 PM
|
1
|
3
|
1916
|
POST
|
Depending on parcel numbers being text or integer, try one of the following: # Text:
query1 = "PARCEL_NO IN ('{}')".format("', '".join(parcelList))
# Integer
query1 = "PARCEL_NO IN ({})".format(", ".join(str(p) for p in parcelList))
>>> parcelList = ['A123', 'B456']
>>> print("PARCEL_NO IN ('{}')".format("', '".join(parcelList)))
PARCEL_NO IN ('A123', 'B456')
>>> parcelList = [123, 456]
>>> print("PARCEL_NO IN ({})".format(", ".join(str(p) for p in parcelList)))
PARCEL_NO IN (123, 456)
... View more
10-28-2020
12:35 PM
|
2
|
1
|
1149
|
POST
|
Since these fields are in the DBOPlotOccJoin table, they would be added after the birth and death dates. The Vettxt is type Boolean or Integer? Is the OccLoc field a duplicate of the UserField4, or is it a bit different? Regarding BirthDate and DeathDate fields, are they type date, or something custom? Sometimes cemetery markers do not give a complete date, so I am curious if there are any rules for handling such dates. I'll take a fresh look at the code and make some suggestions.
... View more
10-27-2020
01:36 PM
|
1
|
6
|
1916
|
POST
|
Did it print a message just before the error? It should have printed something like: "Bad geometry for xxxx-x-xxx". The "AttributeError: 'NoneType' object has no attribute 'extent'" indicates the last feature processed had null or missing geometry. There is a check geometry tool in the ArcToolbox (Data Management Tools > Features > Check Geometry). Use " R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy " as the feature to check. It should find the features with bad geometry.
... View more
10-27-2020
12:48 PM
|
1
|
2
|
1926
|
POST
|
Its possible that your IDE (or Python window in ArcMap) is getting confused over number of spaces or tabs used for indenting. Make sure the 'if row[0] is none:' lines up with the 'sorted_list..', 'list_count..' and comment lines before it. The 'print' line that follows should line up with 'name = fieldValues[0]' and comments starting about 7 lines later.
... View more
10-27-2020
11:42 AM
|
1
|
4
|
1955
|
POST
|
The "Step 3" section would look like this: # 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
if row[0] is None:
print('Bad geometry for {}'.format(row[2]))
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 If the geometry is null or None, then the program should print a message that contains the GIS_ID of the cemetery plot. It will then error out on the next line. Then look for the plot based on this information to see if ArcMap is able to display it. I couldn't find the latest screen capture.
... View more
10-27-2020
10:48 AM
|
1
|
6
|
1955
|
POST
|
I suspect that at least one feature has bad or null geometry. I haven't tested it, but the following might give a clue. Insert it around line 78 - where the comment in the code matches. Of course, make sure the indentation is correct. It will probably still error on the lines following, but it may give us a clue to the issue. # calculate values for point geometry
if row[0] is None:
print('Bad geometry for {}'.format(row[2])) If it does print a "bad geometry" message, see if ArcMap will draw the feature.
... View more
10-27-2020
10:10 AM
|
0
|
8
|
1955
|
POST
|
I noticed you are using a wildcard for your fields. I would avoid this as the fields may be in a different order from what you are expecting. Also, when you say the features both have the identical structure, you mean both field names/types match along with the geometry type and spatial reference? If you are only interested in the geometry and risk field, you might try something like: fc = 'inputFeature' # feature for SearchCursor
tc = 'outputFeature' # feature for InsertCursor
expression = 'some expression'
# you should specify the fields for your search cursor (don't use wildcard)
# this way, you can be sure what they are when you reference them
# also, assuming that fc and tc use the same field 'risk'
fields = ['SHAPE@', 'risk']
# start an insert cursor
insertCursor = arcpy.da.InsertCursor(tc, fields)
with arcpy.da.SearchCursor(fc, fields, where_clause=expression) as cursor:
for row in cursor:
risk_factor = row[1]
if risk_factor == "423123fasq":
# insert feature only if risk_factor is "423123fasq"
insertCursor.insertRow(row)
... View more
10-26-2020
08:34 PM
|
1
|
1
|
5510
|
POST
|
Can you confirm the feature type is a polygon and not a point? # feature with geometry - specifically polygons
fc = r"R:\Jeff\City_Projects\Cemetery\CemeteryMgmt.gdb\BSACemeteriesCopy"
... View more
10-26-2020
01:35 PM
|
0
|
11
|
1914
|
Title | Kudos | Posted |
---|---|---|
1 | 10-27-2016 02:23 PM | |
1 | 09-09-2017 08:27 PM | |
2 | 08-20-2020 06:15 PM | |
1 | 10-21-2021 09:15 PM | |
1 | 07-19-2018 12:33 PM |
Online Status |
Offline
|
Date Last Visited |
07-24-2024
03:05 AM
|