|
POST
|
You could just run a little Python script in the ArcGIS Pro Python window: # path to your point fc
fc = "C:/data/my_database.gdb/Points"
# add GlobalIDs
arcpy.management.AddGlobalIDs(fc)
# add fields
arcpy.management.AddField(fc, "Ward", "TEXT")
arcpy.management.AddField(fc, "Parish", "TEXT")
arcpy.management.AddField(fc, "County", "TEXT")
arcpy.management.AddField(fc, "District", "TEXT")
# trigger updates
arcpy.management.CalculateField(fc, "Ward", "null", "ARCADE")
... View more
04-13-2023
09:28 AM
|
0
|
0
|
4097
|
|
POST
|
As per the snips I'm getting an error saying I need to add global ID's. Is this a pre req to using attribute rules? Yes. Also am I adding this code 4 times but tweaking it for each field or do I leave the field drop down blank? Leave it blank.
... View more
04-13-2023
08:39 AM
|
0
|
0
|
4128
|
|
POST
|
The rule could be something like this: // Calculation Attribute Rule on the point fc
// field: leave empty!
// triggers: insert, update
// load the different polygons into a dictionary where the point fc field names are the keys
var featuresets = {
"Ward": FeaturesetByName($datastore, "Wards", ["Name"], false),
"Parish": FeaturesetByName($datastore, "Parishes", ["Name"], false),
"County": FeaturesetByName($datastore, "Counties", ["Name"], false),
"District": FeaturesetByName($datastore, "Districts", ["Name"], false),
}
// create the result dictionary
var result = {attributes: {}}
for(var field in featuresets) {
// get the first intersecting polygon
var fs = featuresets[field]
var i_fs = First(Intersects(fs, $feature))
// get its name (or null if there is no intersecting polygon)
var name = IIf(i_fs == null, null, i_fs.Name)
// append to the result
result.attributes[field] = name
}
// return the result
return {result: result} It might be better to check the "Exclude from application evaluation" checkbox. This way, only the database executes the rule, not your application (eg ArcGIS Pro). This should make huge bulk updates faster. To trigger this rule for each feature, use the field calculator to calculate any field to be the value that is already in there.
... View more
04-13-2023
08:20 AM
|
0
|
0
|
4131
|
|
POST
|
"Betreff" is German for "Subject". If you look at your post list, the titles are displayed akin to Email subjects: your reply posts are prefixed with "Re:". "Betreff" is just the German version of that. Seems like the user has a German localization.
... View more
04-13-2023
06:51 AM
|
1
|
0
|
922
|
|
POST
|
Oh, that's a very good catch. The problem is line 12. A common problem with Attribute Rules that edit other features is cycling. Imagine line 12 wasn't there. You change the id of feature F1 to be the same as the id of feature F2. The rule will return "Not Unique" for F1 and will instruct ArcGIS to also edit F2 to be "Not Unique". This is an actual edit, meaning that the rule will now trigger for F2. It returns "Not Unique" and instructs ArcGIS to edit F1. This in turn triggers the rule for F1 and so on. You get an infinite cycle (but ArcGIS recognizes that and gives an error instead). We have to have logic that says "hey, we already calculated the uniqueness for this feature, carry on". This is what line 12 does: if the id didn't change in this update, abort. The problem is that the condition is too simple. Here's what happens when you have 3 features F1, F2 & F3, all with id = 5, and you change it to 6 with the field calculator: rule is executed on F1 (original edit). ids = 6, 5, 5. It returns "Unique" for F1 and schedules edits for F2 & F3 to be "Not Unique" (their id is still 5) rule is executed on F2 (edit by F1). Its id didn't change yet, so the rule aborts rule is executed on F3 (edit by F1). Its id didn't change yet, so the rule aborts rule is executed on F2 (original edit). ids = 6, 6, 5. It returns "Not Unique" for F2 and schedules edits for F1 ("Not Unique") & F3 ("Unique") rule is executed on F1 (edit by F2). Its id hasn't changed since the rule was last executed here, so the rule abort. F1 is still "Unique"! rule is executed on F3 (edit by F2). Its id hasn't changed, the rule aborts. rule is executed on F3 (original edit). ids = 6, 6, 6. It returns "Not Unique" for F3 and schedules edits for F1 ("Not Unique") & F2 ("Not Unique") rule is executed on F1 (edit by F3). Its id hasn't changed since the rule was last executed here, so the rule abort. F1 is still "Unique"! rule is executed on F2 (edit by F3). Its id hasn't changed, the rule aborts. So the feature that stays "Unique" was actually the first feature to be calculated. To solve that, we have to let the edit happen if the uniqueness changed since the last update (line 32). So we have to calculate the uniqueness before deciding whether to abort. This leads to more computational demand (which is probably only noticeable for big tables, but still). We can alleviate that by not scheduling an update if the uniqueness of the tested feature didn't change (line 41). As before, change the field names in lines 9, 11, 20, 41, 43, 50. // Calculation ATtribute Rule
// field: leave empty
// triggers: insert, update, delete
// exclude from application evaluation
var mode = $editcontext.editType
// get the new and old id
var ids = [$feature.IntegerField1]
if(mode == "UPDATE") {
Push(ids, $originalfeature.IntegerField1)
}
// get the filtered featuresets and the uniqueness for the ids
var featuresets = []
var uniqueness = []
for(var i in ids) {
// get all features with that id
var id = ids[i]
var query = "IntegerField1 = @ID"
var fs_id = Filter($featureset, query)
Push(featuresets, fs_id)
// count those features (substract the current feature if this is a delete))
var c_id = Count(fs_id)
if(mode == "DELETE") { c_id -= 1 }
// determine the uniqueness
var unique = IIf(c_id > 1, "Not Unique", "Unique")
Push(uniqueness, unique)
}
// abort if this is an UPDATE and the id and the uniqueness didn't change
if(mode == "UPDATE" && ids[0] == ids[1] && uniqueness[0] == uniqueness[1]) { return }
// get the needed updates
var updates = []
for(var i in ids) {
for(var f in featuresets[i]) {
// don't update the current $feature to avoid cycling error
if(f.GlobalID == $feature.GlobalID) { continue }
// don't schedule update if uniqueness didn't change
if(f.TextField2 == uniqueness[i]) { continue }
// store the update to that feature in the update array
var update = {globalID: f.GlobalID, attributes: {TextField1: uniqueness[i]}}
Push(updates, update)
}
}
// return the result and the updates
return {
result: {attributes: {TextField1: uniqueness[0]}},
edit: [{className: "TestPoints", updates: updates}]
}
... View more
04-12-2023
01:16 PM
|
0
|
0
|
3648
|
|
POST
|
I don't think it's possible. You'd need FeaturesetByPortalItem to load the table, and that is not available in the Attribute Rule Calculation profile.
... View more
04-12-2023
04:08 AM
|
1
|
0
|
1718
|
|
POST
|
Thanks for the reply! If you have any idea why my version works via Field Calculator but not as an Attribute Rule, I would love to hear it. Must be something about how a script executes in one environment vs. the other? What follows is pure speculation... I think it has to do with null values. When you validate the script in the field calculator, it picks a feature from the table and runs the script on it to see if there are any errors. When you validate an Attribute Rule, I think it creates a new feature with default values (don't quote me on this, I'm really not sure!). If you have an empty id field, the SQL query will be "DOM1 = null", which is invalid. The correct query would be "DOM1 is null". In the field calculator, your script doesn't see any null value, so it validates. In the Attribute Rule, DOM1 will be null and the script errors out. This script sort of works, but it still doesn't address updating both rows once an ID becomes a duplicate. It should do that, but you might have to refresh the table to see it.
... View more
04-11-2023
10:40 AM
|
1
|
2
|
3680
|
|
POST
|
Backup your data, this will change the geometries! Use the Field Calculator on the Shape field, switch to Arcade, use this script (change the first line to your point fc name) // load your points, define the snap radius
var inlets = FeaturesetByName($datastore, "TestPoints")
var snap_radius = 5
// get the current geometry and create a copy
var geom = Geometry($feature)
var new_geom = Dictionary(Text(geom))
// we want to edit the first and last vertex -> indices 0 and -1
var vertex_indices = [0, -1]
// loop over those indices
for(var v in vertex_indices) {
var i = vertex_indices[v]
// get the vertex
var p = geom.paths[i][i]
// create a buffer around the vertex
var p_buffer = Buffer(p, snap_Radius)
// get the first point that is within the buffer
var p_snap = First(Intersects(p_buffer, inlets))
// no point found? -> skip
if(p_snap == null) { continue }
// change the vertex coordinates to those of the snap point
new_geom.paths[i][i][0] = Geometry(p_snap).X
new_geom.paths[i][i][1] = Geometry(p_snap).Y
// new_geom.paths[i][i][3] = Geometry(p_snap).Z
}
return Polyline(new_geom) Before: After:
... View more
04-11-2023
09:16 AM
|
1
|
0
|
928
|
|
POST
|
You can use a little Python. raster_folder = "C:/data/rasters"
output_folder = ""
output_name = "AreaSumByDay"
# create the output table
table = arcpy.management.CreateTable(output_folder, output_name)
arcpy.management.AddField(table, "Day", "TEXT")
arcpy.management.AddField(table, "SumArea", "FLOAT")
# start inserting values
with arcpy.da.InsertCursor(table, ["Day", "SumArea"]) as cursor:
# loop over the rasters in the folder
arcpy.env.workspace = raster_folder
for raster in arcpy.ListRasters():
# get the day from the raster name
# for example, if your file names look like this: "bla_bla_date.tif"
# you could do it like this:
name = raster.split(".")[0]
day = name.split("_")[-1]
# get the sum of the area field
raster_obj = arcpy.Raster(raster_folder + "/" + raster)
sum_area = arcpy.RasterToNumPyArray(raster_obj).sum()
# write into the table
cursor.insertRow([day, sum_area])
... View more
04-11-2023
08:53 AM
|
1
|
1
|
1344
|
|
POST
|
<Null> is ArcGIS's way of showing that there is no value in a field. What you were trying to do is put the string "<Null>" (which is absolutely not the same as null) into an integer field. ArcGIS can't convert that string into a number, so it errors out. To remove a value from a field, you have to use the null value of the language you're using. None for Python (as Dan told you), Null for VB Script, null for Arcade.
... View more
04-11-2023
06:47 AM
|
0
|
1
|
3925
|
|
POST
|
I used "IntegerField1" as my ID field and "TextField1" as status field. Change those to your field names (lines 9, 11, 36, 43). // Calculation ATtribute Rule
// field: leave empty
// triggers: insert, update, delete
// exclude from application evaluation
var mode = $editcontext.editType
// get the new and old id, do nothing if this is an update that doesn't change the id
var ids = [$feature.IntegerField1]
if(mode == "UPDATE") {
Push(ids, $originalfeature.IntegerField1)
if(ids[0] == ids[-1]) { return }
}
// prepare empty arrays to store the updates and the uniqueness of the ids
var updates = []
var uniqueness = []
// loop over the ids
for(var i in ids) {
// get all features with that id
var id = ids[i]
var query = "IntegerField1 = @ID"
var fs_id = Filter($featureset, query)
// count those features (substract the current feature if this is a delete))
var c_id = Count(fs_id)
if(mode == "DELETE") { c_id -= 1 }
// determine the uniqueness
var unique = IIf(c_id > 1, "Not Unique", "Unique")
Push(uniqueness, unique)
// loop over those features
for(var f in fs_id) {
// skip the current $feature to avoid cycling error
if(f.GlobalID == $feature.GlobalID) { continue }
// store the update to that feature in the update array
var update = {globalID: f.GlobalID, attributes: {TextField1: unique}}
Push(updates, update)
}
}
// return the result and the updates
return {
result: {attributes: {TextField1: uniqueness[0]}},
edit: [{className: "TestPoints", updates: updates}]
}
... View more
04-11-2023
06:37 AM
|
1
|
6
|
3693
|
|
POST
|
Hmm, your images seem to be lost... If you hover over the red square to the left of the attribute rule or over the greyed out save button, ArcGIS tells you what is wrong.
... View more
04-09-2023
02:11 PM
|
0
|
0
|
4174
|
|
POST
|
Hey Casper, just did the survey. A few pointers: I missed a "back" button. You present a definition at the start of each section. I can't go back to check that definition if I have a question in the middle of a section. The use of ArcGIS documentation is problematic. It makes it hard to include GIS users who are accustomed to other GIS software. Sometimes you link to documentation of a concept (like areal interpolation), but often you link the tools directly. Again, bad for non-ArcGIS users and for users not experienced with a certain tool For example, I wondered why you often asked for Euclidian Distance (a tool I'm not familiar with at all). The tool summary says this: "Calculates, for each cell, the Euclidean distance to the closest source.", and there is an image with raster cells. Alright, a tool that works with rasters, not applicable for a point dataset. Except that it is, because you can also use point features as input. A user that used that tool in the past might know that. Users like myself and non-ArcGIS users probably don't. A link that explains the concept of Euclidian distance as opposed to the way it is done in ArcGIS would be way more helpful. Also for you, because you would get more meaningful and fewer wrong answers. "meaningfully applicable" can be tricky. In one question, you ask if you could meaningfully apply a Dissolve on a point layer with a unique field. Yes, you can do that, but the output will be the same as the input. The output is conceptually sound (I think that was part of the definition, again, a back button would be nice), but you didn't do anything meaningful. In some other question, you couldn't apply a tool to a dataset, but you could apply it to a result of an intermediate step. For example, you asked if you can apply areal interpolation to a point dataset. Not directly, but you can apply it to Thiessen polygons you create from the points. Maybe you should clarify that you don't (or do) want to consider intermediate steps.
... View more
04-08-2023
02:34 PM
|
0
|
0
|
1884
|
|
POST
|
The button is also missing in the item page: It is there in the Gallery: After I saw that, I tried if the View type (table/list/grid) in My Content has any effects, but no luck. The button doesn't show up.
... View more
04-06-2023
12:58 PM
|
0
|
0
|
1886
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 01-30-2023 09:57 AM | |
| 1 | 05-18-2023 12:51 AM | |
| 1 | 03-05-2023 12:46 PM | |
| 1 | 12-07-2022 07:01 AM | |
| 1 | 06-21-2022 08:27 AM |
| Online Status |
Offline
|
| Date Last Visited |
02-03-2024
06:14 PM
|