|
POST
|
This may be helpful as an example. It solves a problem that sounds a little like yours. It finds address for sending out notifications to property owners of upcoming tree trimming around power lines. It takes a sub network in a power distribution system identified by a feeder ID. Buffers it to 20 feet finds all of the parcels that the buffer hits. Then gets the owner address from a point feature class and a join. It also dumps out a bunch of feature classes to a FGDB for the mapping folks. So, they can quickly makeup maps for target ares. You can see a select by location used in the select_append_by_buffer function.... """
Tree Trim Generator
"""
import arceditor
import arcpy
import os
import traceback
arcpy.env.overwriteOutput = True
# sde paths dev
sde_pime_overhead = r"xxx"
sde_pime_underground = r"xxx"
sde_sec_overhead = r"xxx"
sde_sec_underground = r"xxx"
sde_support = r"xxx"
sde_moa_parcels = r"xxx"
sde_moa_address = r"xxx"
sde_kpb_parcels = r"xxx"
sde_kpb_address = r"xxx"
sde_service_point = r"xxx"
sde_feeders = r"xxx"
sde_cis_table = r"xxx"
feeder_list_path = r"xxx"
buffer_merge = "xxx"
buffer_dissolve = "xxx"
gdb_kpb_address = r"xxx"
working_gdb = r"Tree_Trim_Data.gdb"
# output feature class names
prime_overhead_buffer = "prime_overhead_buffer"
prime_underground_buffer = "prime_underground_buffer"
sec_overhead_buffer = "sec_overhead_buffer"
sec_underground_buffer = "sec_underground_buffer"
conductors = {sde_pime_overhead: prime_overhead_buffer, sde_pime_underground: prime_underground_buffer,
sde_sec_overhead: sec_overhead_buffer, sde_sec_underground: sec_underground_buffer}
feeder_buffer = "feeder_buffer"
prime_moa_parcels = "moa_parcels"
prime_support = "prime_support"
def get_location_name(name):
name = os.path.basename(name)
if "." in name:
name = name.split(".")[0].lower() + "_" + name.split(".")[1] + "_location"
else:
name = "kpbadm_" + name + "_location"
return name
def get_feederids():
feederids = []
with open(feeder_list_path, "r") as feeders_in:
for line in feeders_in:
feederids.append(line.strip())
feederids_val = []
with arcpy.da.SearchCursor(sde_feeders, ["FEEDERID"]) as feeder:
for row in feeder:
feederids_val.append(row[0])
test = list(set(feederids) - set(feederids_val))
if len(test) != 0:
raise ValueError("Input feeders not valid!:\n\t{}".format(" ".join(test)))
return feederids
def get_oid(source):
oid = None
with arcpy.da.SearchCursor(source, ["OBJECTID"]) as select_serach:
for row in select_serach:
oid = row[0]
break
return oid
def add_feeder_field(location):
arcpy.AddField_management(location, "FEEDERID", "TEXT", field_length=20)
def setup_target_features(source):
arcpy.AddMessage("Makeing local schema for " + os.path.basename(source))
location = get_location_name(source)
oid = get_oid(source)
layer = "layer"
arcpy.MakeFeatureLayer_management(source, layer)
arcpy.SelectLayerByAttribute_management(layer, where_clause="""OBJECTID = {}""".format(oid))
arcpy.CopyFeatures_management(layer, location)
arcpy.TruncateTable_management(location)
if "Service" not in os.path.basename(source):
add_feeder_field(location)
def setup_target_tables(source):
location = get_location_name(source)
oid = get_oid(source)
arcpy.TableSelect_analysis(source, location, """OBJECTID = {}""".format(oid))
arcpy.TruncateTable_management(location)
add_feeder_field(location)
def update_feederids(target, feederid):
add_feeder_field(target)
with arcpy.da.UpdateCursor(target, ["FEEDERID"]) as feeder_cursor:
for row in feeder_cursor:
row[0] = feederid
feeder_cursor.updateRow(row)
def clip_append(source, parcel_temp, feederid):
arcpy.AddMessage("Clipping " + os.path.basename(source) + " for feeder " + feederid)
location = get_location_name(source)
location_temp = location + "_temp"
arcpy.Clip_analysis(source, parcel_temp, location_temp)
if "Service" not in os.path.basename(source):
update_feederids(location_temp, feederid)
arcpy.Append_management(location_temp, location, "NO_TEST")
arcpy.Delete_management(location_temp)
def select_append_by_buffer(source, buffer_lyr, f_id):
arcpy.AddMessage("Selecting " + os.path.basename(source) + " for feeder " + f_id)
location = get_location_name(source)
location_temp = location + "_temp"
source_layer = "source"
arcpy.MakeFeatureLayer_management(source, source_layer)
arcpy.SelectLayerByLocation_management(source_layer, select_features=buffer_lyr)
arcpy.CopyFeatures_management(source_layer, location_temp)
add_feeder_field(location)
update_feederids(location_temp, f_id)
if "Parcel" in os.path.basename(source):
clip_append(sde_service_point, location_temp, f_id)
clip_append(sde_moa_address, location_temp, f_id)
clip_append(sde_kpb_address, location_temp, f_id)
arcpy.Append_management(location_temp, location, 'NO_TEST')
arcpy.Delete_management(location_temp)
def kpb_globalid(kpb):
arcpy.CopyFeatures_management(kpb, gdb_kpb_address)
arcpy.AddGlobalIDs_management(gdb_kpb_address)
def find_features_by_feeder(feature_list, buff_prime):
buffer_layer = "layer_buffer"
arcpy.MakeFeatureLayer_management(buff_prime, buffer_layer)
feeders = get_feederids()
for feature in feature_list:
setup_target_features(feature)
for feeder in feeders:
arcpy.SelectLayerByAttribute_management(buffer_layer, "NEW_SELECTION", """FEEDERID = '{}'""".format(feeder))
select_append_by_buffer(feature_list[0], buffer_layer, feeder)
select_append_by_buffer(feature_list[1], buffer_layer, feeder)
select_append_by_buffer(feature_list[2], buffer_layer, feeder)
arcpy.AddMessage("Dissolving identical...")
arcpy.Dissolve_management("arcfm8_ServicePoint_location", "arcfm8_ServicePoint_location_dissolve",
dissolve_field="SERVLOCNUMBER")
arcpy.AddMessage("Joining CIS info...")
arcpy.JoinField_management("arcfm8_ServicePoint_location_dissolve", "SERVLOCNUMBER", sde_cis_table, "SERVLOCNUMBER")
arcpy.AddField_management("gisadm_Point_Address_location", "GLOBALID_2", "TEXT", field_length=100)
with arcpy.da.UpdateCursor("gisadm_Point_Address_location", ["GLOBALID", "GLOBALID_2"]) as guid_cursor:
for row in guid_cursor:
row[1] = row[0]
guid_cursor.updateRow(row)
arcpy.Dissolve_management("gisadm_Point_Address_location", "gisadm_Point_Address_location_dissolve",
dissolve_field="GLOBALID_2")
arcpy.JoinField_management("gisadm_Point_Address_location_dissolve", "GLOBALID_2", "gisadm_Point_Address_location",
"GLOBALID_2")
arcpy.AddField_management("kpbadm_PhysicalAddress_location", "GLOBALID_2", "TEXT", field_length=100)
with arcpy.da.UpdateCursor("kpbadm_PhysicalAddress_location", ["GLOBALID", "GLOBALID_2"]) as guid_cursor:
for row in guid_cursor:
row[1] = row[0]
guid_cursor.updateRow(row)
arcpy.Dissolve_management("kpbadm_PhysicalAddress_location", "kpbadm_PhysicalAddress_location_dissolve",
dissolve_field="GLOBALID_2")
arcpy.JoinField_management("kpbadm_PhysicalAddress_location_dissolve", "GLOBALID_2", "kpbadm_PhysicalAddress_location",
"GLOBALID_2")
arcpy.Dissolve_management("kpbadm_PhysicalAddress_location", "kpbadm_PhysicalAddress_location" + "_dissolve",
dissolve_field="FEEDERID")
arcpy.Dissolve_management("gisadm_Parcel_Areas_location", "gisadm_Parcel_Areas_location" + "_dissolve",
dissolve_field="FEEDERID")
arcpy.Dissolve_management("kpbadm_Parcels_location", "kpbadm_Parcels_location" + "_dissolve", dissolve_field="FEEDERID")
if __name__ == "__main__":
# let user know the data sources
arcpy.AddMessage("MOA Parcels Source: "
+ os.path.join(os.path.basename(os.path.dirname(sde_moa_parcels)),
os.path.basename(sde_moa_parcels)))
# delete feature classes if they exist
arcpy.env.workspace = working_gdb
feature_class_list = arcpy.ListFeatureClasses()
if feature_class_list is not None:
for feature_class in feature_class_list:
if arcpy.Exists(feature_class):
arcpy.AddMessage("Deleting existing feature: " + feature_class)
arcpy.Delete_management(feature_class)
# do geoprocessing
kpb_globalid(sde_kpb_address)
for k, v in conductors.items():
arcpy.AddMessage("Buffering: {}".format(os.path.basename(k)))
arcpy.Buffer_analysis(k, v, 20, dissolve_field="FEEDERID", dissolve_option="LIST")
arcpy.Merge_management([v for k, v in conductors.items()], buffer_merge)
arcpy.Dissolve_management(buffer_merge, buffer_dissolve, "FEEDERID")
#find_features_by_feeder([gdb_kpb_address], buffer_dissolve)
find_features_by_feeder([sde_moa_parcels, sde_kpb_parcels, sde_support, sde_moa_address, gdb_kpb_address,
sde_service_point], buffer_dissolve)
... View more
03-13-2019
09:36 AM
|
2
|
0
|
3946
|
|
POST
|
I am looking forward to pro and python 3.x for sure. But we are stuck at 10.6.1 for years because of other software dependencies. We were at python 2.7.3 and 2.7.2 (arc 10.1 1 and 10.2). It was problematic, e.g. pip stopped working and we had to go to wheel files, web scrapers stopped working because of changes to ssl... etc. I am just unhappy with the situation.
... View more
03-12-2019
09:29 AM
|
2
|
0
|
1321
|
|
POST
|
How is the end of support for python 2.7 next year going to impact arcmap 10.6 which is supported until 2024 and uses python 2.7.14 and Numerical Python 1.9.3. My gut says that this could be painful, e.g. no pip and no support for many popular packages. Thoughts? Python 2.7 Countdown Esri Support ArcMap 10.6 (10.6.1)
... View more
03-11-2019
02:52 PM
|
1
|
2
|
2553
|
|
POST
|
Thanks for the feedback Peter. Looks like we were confused. We thought that we could not create a cached image service without the extension. As, you point out this is not the case. I created one today. We will look at setting up new server for just imagery in the future if we need the more advanced functions from the image server extension.
... View more
03-04-2019
03:56 PM
|
0
|
0
|
1380
|
|
POST
|
We are considering adding the image server extension to our environment. We are wondering what the best practice is from a server architecture point of view. Can we just add it to our existing servers? Or should we stand up new servers dedicated to imagery? What are environment looks like: 200 employees, but only a sub set are hitting the servers at any one time 10.6.1 Portal (federated, web adapter) prod, test, dev 10.4.1 AGS prod, test, dev The imminent need is to server a 65GB tile cache in both the 10.6.1 and 10.4.1 environments.
... View more
03-01-2019
03:48 PM
|
0
|
2
|
1530
|
|
POST
|
I would suggest the same thing as Curtis... Get your output location as a parameter. Don't count on the arcpy.env.workspace setting and pass your full path... something like: final_raster.save(output_path) Raster—ArcPy classes | ArcGIS Desktop One thing that I find helps a lot is to get everything working in a python IED with hardcoded parameters before turning it into a "script tool". That way you can take advantage of debuggers, etc. (helps cut down on the black box effect). https://www.jetbrains.com/pycharm/download/#section=windows GitHub - pyscripter/pyscripter: Pyscripter is a feature-rich but lightweight Python IDE
... View more
02-22-2019
09:59 AM
|
2
|
2
|
5731
|
|
POST
|
I am making a script that will find, primarily, database (sde) connection information for each layer and table view within each mxd that has been published as a service across a number of ArcGIS servers. Then it inserts the info back into an Oracle table. This is to help with administration. So, I have it working for layers via the service properties attribute. But I don't see a service properties like attribute for a table view object? How can I get database user name (for DBA connections) and the database server for tables in an mxd? The only thing I see like this is the table data source. TableView—Help | ArcGIS for Desktop Layer—Help | ArcGIS for Desktop Please see my two functions below. The working layers one and the table view outline... Thanks for the help!! def find_conn_prop_tbl(mxd_source):
ags = mxd_source[1].split(os.path.sep)[2]
ags_service = os.path.basename(mxd_source[1])[:-4]
ags_service_path = mxd_source[1]
toc_type = 'table_view'
mxd = arcpy.mapping.MapDocument(mxd_source[0])
for df in arcpy.mapping.ListDataFrames(mxd):
if df is not None:
data_frame_name = df.name
table_list = arcpy.mapping.ListTableViews(mxd, "", df)
if table_list is not None:
for table in table_list:
# ?????????
del table
del table_list
del mxd, df
def find_conn_prop_fc(mxd_source):
ags = mxd_source[1].split(os.path.sep)[2]
ags_service = os.path.basename(mxd_source[1])[:-4]
ags_service_path = mxd_source[1]
toc_type = 'layer'
mxd = arcpy.mapping.MapDocument(mxd_source[0])
for df in arcpy.mapping.ListDataFrames(mxd):
if df is not None:
data_frame_name = df.name
layer_list = arcpy.mapping.ListLayers(mxd, "", df)
if layer_list is not None:
for layer in layer_list:
if layer.supports('SERVICEPROPERTIES'):
toc_path = layer.longName
prop_dict = layer.serviceProperties
prop_dict['AGS'] = ags
prop_dict['AGS_Service'] = ags_service
prop_dict['AGS_Service_Path'] = ags_service_path
prop_dict['TOC_Path'] = toc_path
prop_dict['TOC_Type'] = toc_type
prop_dict['Data_Frame'] = data_frame_name
oracle_injector.inject(prop_dict)
del layer
del layer_list
del mxd, df
... View more
02-21-2019
03:44 PM
|
0
|
1
|
1492
|
|
POST
|
Did you find a solution to this? We have an old database presting an identical error as yours, save the table name. I tried to add the network to a map while connected as the data owner and I still get the same error...
... View more
02-19-2019
02:18 PM
|
0
|
0
|
1490
|
|
POST
|
This is the script we use to stop and start a geocode service. I think it is basically a cut and past of an esri one. We are using http and 6080: """
Stop or start ArcGIS Server geocode service
"""
# Required imports
import urllib
import urllib2
import json
import contextlib ## context manager to clean up resources when exiting a 'with' block
def get_token(adminUser, adminPass, server, port, expiration):
"""
Function to generate a token from ArcGIS Server; returns token.
http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000000m5000000.htm
:param adminUser: admin user
:param adminPass: admin password
:param server: AGS name, e.g. ceav456
:param port: server port
:param expiration: token timeout
:return:
"""
# Build URL
url = "http://{}:{}/arcgis/admin/generateToken?f=json".format(server, port)
# Encode the query string
query_dict = {
'username': adminUser,
'password': adminPass,
'expiration': str(expiration), ## Token timeout in minutes; default is 60 minutes.
'client': 'requestip'
}
query_string = urllib.urlencode(query_dict)
try:
# Request the token
with contextlib.closing(urllib2.urlopen(url, query_string)) as jsonResponse:
getTokenResult = json.loads(jsonResponse.read())
## Validate result
if "token" not in getTokenResult or getTokenResult == None:
raise Exception("Failed to get token: {}".format(getTokenResult['messages']))
else:
return getTokenResult['token']
except urllib2.URLError, e:
raise Exception("Could not connect to machine {} on port {}\n{}".format(server, port, e))
# Function to start or stop a service on ArcGIS Server; returns JSON response.
## http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000001s6000000.htm
def service_start_stop(server, port, svc, action, token):
"""
Function to start or stop a service on ArcGIS Server; returns JSON response.
http://resources.arcgis.com/en/help/arcgis-rest-api/02r3/02r3000001s6000000.htm
:param server: AGS name, e.g. ceav456
:param port: server port
:param svc: service name, folder, and type
:param action: start or stop service
:param token: server token
:return: json response
"""
# Build URL
url = "http://{}:{}/arcgis/admin".format(server, port)
requestURL = url + "/services/{}/{}".format(svc, action)
# Encode the query string
query_dict = {
"token": token,
"f": "json"
}
query_string = urllib.urlencode(query_dict)
# Send the server request and return the JSON response
with contextlib.closing(urllib.urlopen(requestURL, query_string)) as jsonResponse:
return json.loads(jsonResponse.read())
def service_control(ags, action):
"""
Control server services
:param ags: AGS (ArcGIS Server)
:param action: start or stop
:return: result string
"""
# Local variables
# Authentication
adminUser = r"siteadmin"
adminPass = r"sit3mngr!"
# ArcGIS Server Machine
server = ags
port = "6080"
# Services ("FolderName/ServiceName.ServiceType")
svc = "Locators/CW_Composite.GeocodeServer"
# Get ArcGIS Server token
expiration = 60 ## Token timeout in minutes; default is 60 minutes.
token = get_token(adminUser, adminPass, server, port, expiration)
# Perform action on service
jsonOuput = service_start_stop(server, port, svc, action, token)
## Validate JSON object result
if jsonOuput['status'] == "success":
result = "{} {} successful on server {}".format(action.title(), str(svc), server)
else:
result = "Failed to {} {}".format(action, str(svc))
return result
raise Exception(jsonOuput)
return result
... View more
02-15-2019
02:28 PM
|
0
|
0
|
4338
|
|
POST
|
We are wondering if there is a standardized output for geocoders. We noticed that an out of the box 10.6 single house with subaddress has a fair amount of variation from our older custom style single house with units. I think the only thing that is custom is the attributes UnitType and UnitNumber. 10.6 single house with subaddress json response {
"spatialReference": {
"wkid": 102634,
"latestWkid": 102634
},
"candidates": [
{
"address": "3850 TAIGA DR, Anchorage, AK, 99516",
"location": {
"x": 1674055.943784937,
"y": 2594838.6101037711
},
"score": 100,
"attributes": {
"Score": 100,
"Match_addr": "3850 TAIGA DR, Anchorage, AK, 99516",
"Addr_type": "SubAddress",
"AddNum": "3850",
"Side": "",
"StPreDir": "",
"StPreType": "",
"StName": "TAIGA",
"StType": "DR",
"StDir": "",
"SubAddType": "",
"SubAddUnit": "",
"StAddr": "3850 TAIGA DR",
"City": "Anchorage",
"County": "",
"State": "AK",
"StateAbbr": "AK",
"ZIP": "99516",
"Country": "USA",
"LangCode": "",
"Distance": 0,
"X": 1674055.9437849999,
"Y": 2594838.6101040002,
"DisplayX": null,
"DisplayY": null,
"Xmin": null,
"Xmax": null,
"Ymin": null,
"Ymax": null
},
"extent": {
"xmin": 1673399.7771182703,
"ymin": 2594182.4434371046,
"xmax": 1674712.1104516038,
"ymax": 2595494.7767704376
}
}
]
} custom style single house with units json response {
"spatialReference": {
"wkid": 102634,
"latestWkid": 102634
},
"candidates": [
{
"address": "3850 TAIGA DR, Anchorage, AK 99516",
"location": {
"x": 1674055.9457335561,
"y": 2594838.6066555073
},
"score": 88.840000000000003,
"attributes": {
"Loc_name": "ARCFM8CW_Parce",
"Score": 88.840000000000003,
"Match_addr": "3850 TAIGA DR, Anchorage, AK 99516",
"House": "3850",
"PreDir": "",
"PreType": "",
"StreetName": "TAIGA",
"SufType": "DR",
"SufDir": "",
"UnitType": "",
"UnitNumber": "",
"City": "Anchorage",
"State": "AK",
"ZIP": "99516",
"User_fld": "0",
"Addr_type": "Address",
"Side": "",
"FromAddr": "",
"ToAddr": ""
}
}, We have a vendor asserting that our coder in returning poor information for 3850 Taiga Dr. The variation is in the field names. For example, StreetName vs. StName. Is StreetName an old standard from the 10.0 days and now it is StName. I am guessing that the output field names are driven by the geocoder style xml. Is that right?
... View more
02-13-2019
02:45 PM
|
0
|
1
|
2012
|
|
POST
|
So, I did talk to esri about this one. They say the arcpy tools just hits the oracle tools. The arcpy tools are not doing anything extra or special. However, with that said the still recommend running the tools via arcpy. I never got any supporting documentation for why this is. We did end up implementing the arcpy tools based on esri recommendation.
... View more
01-07-2019
03:02 PM
|
1
|
0
|
3931
|
|
POST
|
People did not like the shapefile solution... So... def field_validation(feature_class):
field_list = arcpy.ListFields(feature_class)
validation = True
logger.info(ceaarcpy.indent("Field length validation", 2))
for f in field_list:
if len(f.name) > 30:
validation = False
if validation is False:
logger.info(ceaarcpy.indent("Validation fail, modifying feature class schema", 2))
output_location = os.path.dirname(feature_class)
feature_class_temp = feature_class + "_temp"
feature_class_describe = arcpy.Describe(feature_class)
if arcpy.Exists(feature_class_temp):
arcpy.Delete_management(feature_class_temp)
arcpy.CreateFeatureclass_management(out_path=output_location,
out_name=os.path.basename(feature_class_temp),
geometry_type=feature_class_describe.shapeType,
spatial_reference=feature_class_describe.spatialReference)
mod_field = {}
for f in field_list:
if f.name not in ["OBJECTID", "Shape", "Shape_Length"]:
f_length = f.length
f_name = f.name
f_type = f.type
f_precision = f.precision
f_scale = f.scale
if len(f_name) > 30:
mod_field[f_name] = f_name[:29]
f_name = f_name[:29]
arcpy.AddField_management(in_table=feature_class_temp,
field_name=f_name,
field_type=f_type,
field_length=None if f_length == 0 else f_length,
field_precision=None if f_length == 0 else f_precision,
field_scale=None if f_scale == 0 else f_scale)
fieldmapping = arcpy.FieldMappings()
fieldmapping.addTable(feature_class)
for input_field, output_field in mod_field.items():
field_map = fieldmapping.getFieldMap(fieldmapping.findFieldMapIndex(input_field))
temp = field_map.outputField
temp.name = output_field
field_map.outputField = temp
fieldmapping.replaceFieldMap(fieldmapping.findFieldMapIndex(input_field), field_map)
arcpy.Append_management(feature_class, feature_class_temp, "NO_TEST", fieldmapping)
arcpy.Delete_management(feature_class)
arcpy.Rename_management(feature_class_temp, feature_class)
... View more
11-28-2018
12:44 PM
|
1
|
0
|
1779
|
|
POST
|
Ya, I think the most elegant solution would be to build a new schema in the FGDB and then append. My number 2 option. I was hoping there was some cool esri way to do it.. So, in the interest of time I put the shapefile export/import fix into production, as that is only 15 lines of code or so... If I don't get any user push back I am going to call it good
... View more
11-20-2018
04:13 PM
|
1
|
1
|
1779
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-04-2024 05:39 PM | |
| 1 | 07-30-2024 09:05 AM | |
| 1 | 07-08-2024 05:32 PM | |
| 1 | 03-20-2024 10:27 AM | |
| 6 | 03-13-2024 03:38 PM |
| Online Status |
Offline
|
| Date Last Visited |
11-12-2025
11:02 AM
|