|
POST
|
It works as it should for me (tested in Firefox and Edge).
... View more
03-01-2021
10:33 PM
|
0
|
0
|
1223
|
|
POST
|
So where it says "Hazard", it should say "n/a", right? Or is "Hazard" a land use? Can you post the code you used, please?
... View more
03-01-2021
09:55 PM
|
0
|
4
|
3579
|
|
POST
|
"Hazard" is the name of the variable that stores your text. You can call it pretty much anything you want, though descriptive names are the most sensible. // Get all features of the LandUse layer that are intersected by the selected feature.
// You apply a negative buffer here, so you don't get land use features that only intersect with the outer edges, is that correct?
var intersect_layer = Intersects(FeatureSetByName($map, "LandUse - h Provision Overlay"), Buffer($feature, -10, 'feet'))
// Define and initialize the variable that stores your text
var intersected_land_uses = ""
// Loop through the intersecting land use features
for (var f in intersect_layer ) {
var land_use = IIF(IsEmpty(f.NAME), "n/a", f.NAME)
if (intersected_land_uses == "") { // there is nothing in here yet
intersected_land_uses = land_use
} else { // there is something in here already, append with " And "
intersected_land_uses += " And " + land_use
}
}
return intersected_land_uses
... View more
02-25-2021
07:51 AM
|
0
|
6
|
3622
|
|
POST
|
I think Jeff meant something like this: import arcpy
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = ""
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [SomeTool, AnotherTool,]
class BaseTool(object):
# This class contains all methods that are used by multiple tools in the toolbox.
def Procedure1(self, parameter1, parameter2):
#This is a procedure used by multiple tools in the pyt file.
#code goes here...
def Procedure2(self, parameter1):
#This is a procedure used by multiple tools in the pyt file.
#code goes here...
self.Procedure3('something')
def Procedure3(self, parameter1):
#This is a procedure used by Procedure2
#code goes here...
class SomeTool(BaseTool): # this class inherits every method from BaseTool
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Some Tool"
self.description = " "
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
params = None
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
# BaseTool contains Procedure1 and Procedure2, and SomeTool inherits them, so you can just call them with self.Procedure1
aVariable = self.Procedure4('blah')
self.Procedure1(aVariable,'something else')
self.Procedure2('something else')
def Procedure4(inParameter):
#This procedure is just for SomeTool
#code goes here...
class AnotherTool(BaseTool):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Another Tool"
self.description = " "
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
params = None
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
self.Procedure2('something else')
... View more
02-24-2021
10:36 PM
|
3
|
1
|
2606
|
|
POST
|
As you have found, it is not possible to update Y from the join with X. What you can do: create a relationship class joining X and Y select an X feature (in the map or in the table) open the Attributes pane (Map/Edit -> Selection -> Attributes) click on the triangle to the left of your selected feature, this shows a list of all exisiting relationships navigate to your Y entry and edit it, apply (or auto apply)
... View more
02-24-2021
03:26 AM
|
1
|
0
|
3608
|
|
POST
|
If your flight tables are in the same datastore as the county layer, it should be doable with a popup. I wouldn't do it, though, because it is quite complex, it would be lots of work converting your Python code to Arcade and the Arcade code wouldn't be very maintainable. If you want to look into it, these would be starting points: Arcade start page Arcade function reference , especially FeatureSetByName() and Filter() In your case, I would create a Python toolbox. This way, you can use your existing code, and it's not too much extra work for your users. The only problem is that you can't display clickable HTML links in the tool messages. Possible workaround: Modify your existing code, so that it builds an HTML document and then open that document in the user's default browser. # Toolbox.pyt
# File can be created from ArcGIS Pro Catalog
import arcpy
import os
import webbrowser
class Toolbox(object):
def __init__(self):
self.label = "Toolbox"
self.alias = ""
self.tools = [Tool]
class Tool(object):
def __init__(self):
self.label = "Tool"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
# optional parameter, where your users can select a county from a list
params = [
arcpy.Parameter(name="county", displayName="County", datatype="GPString", parameterType="Optional", direction="Input"),
]
params[0].filter.list = [row[0] for row in arcpy.da.SearchCursor("CountyFeatureclass", ["CountyNameField"])]
return params
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
if not parameters[0].value:
parameters[0].setWarningMessage("If you don't select a county from this list, you have to select one in the map!")
def execute(self, parameters, messages):
# get county from user input
county = parameters[0].value
if not county:
# user didn't choose from the dropdown list
# search layer for selection
county_layer = arcpy.mp.ArcGISProject("current").activeMap.listLayers("CountyLayerName")[0]
selection = county_layer.getSelectionSet()
if len(selection) == 0:
# user didn't select a county -> error
arcpy.AddError("You have to select a county!")
if len(selection) > 1:
# user selected multiple counties
# here, I just print a warning and then pick the first one
# you could handle this differently
arcpy.AddWarning("Multiple counties selected, only one will be used!")
county = [row[0] for row in arcpy.da.SearchCursor(county_layer, ["CountyNameField"])][0]
arcpy.AddMessage("Selected county: {}".format(county))
# either call your code or paste it here
pass
# build an HTML file in the user's home directory
html_file = os.path.join(os.path.expanduser("~"), "flight_connections.html")
with open(html_file, "w") as f:
f.write("<html>\n")
# ...
f.write("</html>")
# open the HTML file
webbrowser.open(html_file) Starting points: What is a Python toolbox What is arcpy Arcpy reference
... View more
02-24-2021
01:31 AM
|
0
|
0
|
1480
|
|
POST
|
You can specify the full name of the database sequence. If all databases are in the same datastore, this might work (can't test, since I have only one database): NextSequenceValue("SequenceDatabaseName.SequenceOwner.SequenceName") Alternatively, you could define a sequence called "AssetID" in all databases and append a domain name, so that all assets have a unique id: // water database:
"Water-" + NextSequenceValue("AssetID")
// sewer database:
"Sewer-" + NextSequenceValue("AssetID")
// this gives you these asset ids:
// Water-1, Water-2, ..., Water-6379
// Sewer-1, Sewer-2, ..., Sewer-6379
... View more
02-23-2021
06:53 AM
|
0
|
0
|
2475
|
|
POST
|
"I have a front end on the ArcGIS Pro" - Does this mean your users work with the actual ArcGIS Pro, or have you built a web map / web app? "Can I send an HTTP Request or any sort of API request from the front end to the Python Code" In ArcGIS Pro, your users could use the Python window to manually type in the code. AFAIK, there is no way to execute Python code by clicking on a feature. If you built a custom web app, you might be able to do something like that by using the javascript API. Alternatives: Build an addon for ArcGIS Pro Build a geoprocessing tool for ArcGIS Pro. The user selects a county in the map and then runs the tool. The tool searches the layer (either given as input by the user or hard coded if it's always the same) and only finds the selected feature(s). Then you can run your existing python code using the found values. Depending on the complexity of what you want to do with the county, defining a popup might do the trick. Arcade can do some great stuff. From your question, it sounds like the popup solution would be the most comfortable for your users. What does your Python code do?
... View more
02-22-2021
01:17 AM
|
0
|
2
|
1491
|
|
POST
|
Haha, I didn't even think of the Text() function... Disregard the above, use this instead: return "ADA-" + Text(NextSequenceValue("ADA"), "0000000")
... View more
02-16-2021
01:13 AM
|
3
|
1
|
2461
|
|
POST
|
// next sequence value as string
var ada = "" + NextSequenceValue("ADA")
// there doesn't seem to be a while loop in Arcade,
// but we can fake one with a for loop...
for(var i = 0; i < 100; i++) {
if(Count(ada) >= 7) {
break
}
ada = "0" + ada
}
return "ADA-" + ada
... View more
02-16-2021
01:04 AM
|
0
|
2
|
2462
|
|
POST
|
// Calculation Attribute Rule for your point FC
// Field: NearestLineObjectID
// Triggers: Insert (, Update)
// Get your line FC
var line_fs = FeatureSetByName($datastore, "FullNameOfLineFeatureclass", ["ObjectID"], true)
// If you have many lines, just select those that are within a certain distance of your point
// I tested it without this line and around 10.000 line features and it took a good time to compute. With this line it was done almost instantly.
// Choose a distance in which a line feature will certainly be!
line_fs = Intersects(line_fs, Buffer($feature, 100, "Meters"))
// Cycle through the line features and find the nearest one
var min_dist = 999999 // arbitrary large number
var nearest_line_oid = null
var geo = Geometry($feature)
for(var line in line_fs) {
var line_geo = Geometry(line)
var dist = Distance(geo, line_geo)
if(dist < min_dist) {
min_dist = dist
nearest_line_oid = line.ObjectID
}
}
// Return the ObjectID of the nearest line feature
return nearest_line_oid This will only work when you insert or update point features. If you insert or edit a line feature that would place it nearer to a point than another line, you have to update the point! Or, you could add an Attribute Rule to the line featureclass that updates the point featureclass when you edit a line. Let me know if you need help with that. @HusseinNasser2: This should probably be moved to the Attribute Rules group.
... View more
02-10-2021
02:02 AM
|
5
|
4
|
4593
|
|
POST
|
@LindseyStone wrote: So with your above coding would this be right? With this being in an SDE geodatabase shared out to a feature service for the datastore do I need to fill that out or do water.waterdevice or fill out the hydrant FC differently? "WaterDevice" should be "DatabaseName.DataOwner.WaterDevice", the full name you get shown in the Catalog View. $datastore is a global Arcade variable that references the server that hosts your service. You don't need to change it.
... View more
02-07-2021
10:46 PM
|
0
|
0
|
7085
|
|
POST
|
If Utility_AssetID is NOT the field relating these tables (i.e. you have another field that is shared by both), you can do it this way: // rule in Inspection table
// triggers: insert, update
// field: Utility_AssetID
// value of shared field
var key = $feature["SharedField"]
// search for related features in Hydrant Devices FC
var hydrant_devices = FeatureSetByName($datastore, "NameOfHydrantDevicesFC", ["SharedField", "Utility_AssetID"], false)
var filtered_devices = Filter(hydrant_devices, "SharedField = @key")
// no related features found
if(Count(filtered_devices) == 0) {
return null
}
// related feature(s) found -> return Utility_AssetID of the first one
return First(filtered_devices)["Utility_AssetID"] If Utility_AssetID IS the field relating your FC and table (i.e. it's the only field telling you to which hydrant an inspection belongs), you can't do this with an Attribute Rule (at least not that I know of). What you can do in this case: create a Relationship Class between the FC and the table in ArcGIS Pro: select a hydrant open the Attributes pane (Map/Edit --> Selection --> Attributes) below your selected hydrant feature, you should see the name of the Relationship Class right click on that, select "Add new to relationship" ArcGIS creates a new entry in your inspection table, filling the AssetID with the value from the feature
... View more
02-04-2021
10:49 PM
|
2
|
0
|
7101
|
|
POST
|
For now, you'll have to define two rules for that, according to this post , they can be combined into one rule in ArcGIS Pro 2.7. // Rule: TrackAttributeEdits
// Field: AttributeChanged
// Triggers: Insert, Update
// new entry
if(IsEmpty($originalfeature["AttributeChanged"])) {
return Now()
}
// define the checked attributes as [ [old, new] ]
// do not put things like Shape, AttributeChanged, GeometryChanged or editor tracking fields here!
var monitored_attributes = [
[$originalfeature["Attribute1"], $feature["Attribute1"]],
[$originalfeature["Attribute2"], $feature["Attribute2"]],
]
// check those attributes, return Now() at the first changed one
for(var a in monitored_attributes) {
var old_att = monitored_attributes[a][0]
var new_att = monitored_attributes[a][1]
if(old_att != new_att) {
return Now()
}
}
// nothing changed
return $feature["AttributeChanged"] // Rule: TrackGeometryEdits
// Field: GeometryChanged
// Triggers: Insert, Update
// new entry
if(IsEmpty(Geometry($originalfeature))) {
return Now()
}
// compare geometries
var old_geo = Geometry($originalfeature)
var new_geo = Geometry($feature)
if(!Equals(old_geo, new_geo)) {
return Now()
}
// nothing changed
return $feature["GeometryChanged"]
... View more
01-29-2021
01:06 AM
|
3
|
1
|
1094
|
|
POST
|
I'm not the OP, but I've got the same problem... The idea isn't to choose a field name, but the field value. For example, imagine a tool that exports data from a user-specified row to Excel. The user opens the tool and sees a dropdown list of existing values in a field of the table, eg permit codes or parcel numbers. In the python toolbox, you can populate that list with something like this: class Tool:
def getParameterInfo(self):
p0 = arcpy.Parameter(...)
with arcpy.da.SearchCursor(layer_or_table, [field]) as cursor:
p0.filter.list = [row[0] for row in cursor]
return [p0] Each time you start that tool in Pro, it searches the specified layer/table for values. If you add a new value, it will be shown in the dropdown list the next time you start the tool. When you publish that tool, you get a static list of values that were in the layer/table when you published. New entires won't be shown.
... View more
01-04-2021
02:32 AM
|
1
|
0
|
1116
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 03-05-2023 12:46 PM | |
| 1 | 12-07-2022 07:01 AM | |
| 1 | 06-21-2022 08:27 AM | |
| 1 | 09-18-2023 04:55 AM | |
| 1 | 11-07-2022 11:15 PM |
| Online Status |
Offline
|
| Date Last Visited |
02-03-2024
06:14 PM
|