|
POST
|
You're checking the layer for null, which it never will be. What you want to do: get the first element of the intersect if there is no intersection, the intersect fs will be empty. calling First() on an empty fs will return null check that element for null var evac_fs = FeatureSetByName($map,"RDNO Evacuation Areas")
var evac = First(Intersects(evac_fs, $feature))
return IIf(evac == null, "None", evac.Type)
... View more
05-18-2023
12:51 AM
|
1
|
0
|
1453
|
|
POST
|
There's no function to project coordinates, but there is an Idea to add one, lend your support there to hopefully get that functionality someday.
... View more
05-18-2023
12:45 AM
|
3
|
0
|
3347
|
|
POST
|
Buffer your channel line fc Summarize Within Input Polygons: the buffered channel Summary Features: the Soil Type fc, the Land Use fc Group Field: fields that specify soil type and land use
... View more
05-18-2023
12:40 AM
|
2
|
1
|
1955
|
|
IDEA
|
Joining two Featuresets in Arcade is frickly. You have to manually create a new featureset, iterate through the input fs, Filter() the corresponding Feature from the join fs, and copy all attributes from both Featuresets. This is not only a lot of code for a simple operation, but using Filter() in a loop massively impacts performance, so either you write even more code to load the Featuresets into RAM (until it is hopefully added into native Arcade functionality) or your expression is really slow. Joining Featuresets is one of the most basic database/GIS operations and really should be a native function. Especially now, as Arcade gains popularity. I answered multiple questions about joining fields in the last weeks. The current way to do it is absolutely not suited for new or inexperience users. And lacking such basic functionality really isn't a great look for a language focused on data manipulation. I envision something like this: var in_fs = FeaturesetByPortalItem(...)
var join_fs = FeaturesetByPortalItem(...)
# option 1: single field key, join all fields
var joined_fs = Join(in_fs, "PrimaryKey", join_fs, "ForeignKey")
# option 2: multiple fields key, select fields to join
var joined_fs = Join(in_fs, ["PrimaryKey1", "PrimaryKey2"], join_fs, ["ForeignKey1", "ForeignKey2"], ["JoinField1", "JoinField2", "JoinField3"]) So the signature would be something like this Join(inFS, primaryKeys, joinFS, foreignKeys, joinFields=["*"])
... View more
05-17-2023
12:54 PM
|
26
|
2
|
3306
|
|
POST
|
I assume it might have something to do with the number of records I got the same error for Multipoints with only 1 point, so I don't think that's it. My first idea was that it had something to do with the SpatialReference, because you don't set that when creating the Multipoints, but that didn't work either. My tests suggest that something is buggy with constructed Multipoints. def layer_to_multipoint(layer, wkid=None):
"""Reads the geometries of a point layer and returns a Multipoint geometry.
If wkid is set, the Multipoint will be projected into that system.
"""
in_sr = arcpy.Describe(layer).spatialReference
coordinates = [row[0] for row in arcpy.da.SearchCursor(layer, ["SHAPE@XY"])]
points = [arcpy.Point(*c) for c in coordinates]
multipoint = arcpy.Multipoint(arcpy.Array(points), spatial_reference=in_sr)
if wkid:
out_sr = arcpy.SpatialReference(wkid)
multipoint = multipoint.projectAs(out_sr)
return multipoint
# construct a MP geometry from a point layer
constructed_mp = layer_to_multipoint("TestPoints")
# try to run some geometry functions on it
constructed_mp.symmetricDifference(constructed_mp) # ERROR
constructed_mp.union(constructed_mp) # ERROR
constructed_mp.difference(constructed_mp) # works
constructed_mp.intersect(constructed_mp, 1) # works
# write the constructed mp into a fc and read it again from there
with arcpy.da.InsertCursor("TestMultipoints", ["SHAPE@"]) as cursor:
cursor.insertRow([constructed_mp])
read_mp = [r for r in arcpy.da.SearchCursor("TestMultipoints", ["SHAPE@"])][0][0]
# try to run the geometry functions on the read mp
read_mp.symmetricDifference(read_mp) # works
read_mp .union(read_mp) # works
read_mp .difference(read_mp) # works
read_mp .intersect(read_mp , 1) # works
# let's compare the mp's
print(constructed_mp.JSON)
#{"points":[[81359.018400000408,5906093.2276000008],[81356.343299999833,5906139.3099000007],[81519.05449999962,5905955.2974999994]],"spatialReference":{"wkid":25833,"latestWkid":25833}}
print(read_mp.JSON)
#{"points":[[81359.018400000408,5906093.2276000008],[81356.343299999833,5906139.3099000007],[81519.05449999962,5905955.2974999994]],"spatialReference":{"wkid":25833,"latestWkid":25833}} It seems like these are the same Multipoints, but somehow union and symmetricDifference fail for the mp I constructed myself. It also didn't matter whether I used the functions, the operators, or the Geometry._arc_object functions. I think I remember you posting a huge script containing this snippet. Did it work back then? I think this is a matter for tech support. In the meantime, there's Symmetrical Difference...
... View more
05-17-2023
12:34 PM
|
0
|
1
|
1873
|
|
POST
|
Hmm, so you can't use OutrunNumber to get the other line parts. In that case you need to use the geometries, which will be more complicated. If you could upload a part of your two feature classes (either here or in a private message), that would be helpful. Does this come close to what you want to do? If a line intersects a Device with AssetGroup 37, copy its OutrunNumber If a line does not intersect such a Device, Try to get the OutrunNumber from intersecting lines
... View more
05-17-2023
11:51 AM
|
1
|
0
|
2554
|
|
POST
|
Just answered on the Idea you posted. Ideas are for improvements you want to propose. Let's talk about this question here. You have to join the Variant field to the grouped Featureset. There is no native function to join a field, so you have to do it yourself: // group by date and site, getting the max frequency
var grouped_fs = GroupBy(fs, ['Sample_Date', 'Site_ID'], [{name: 'Estimated_Frequency_Reads', expression: 'Estimated_Frequency_Reads', statistic: 'MAX' }] )
// create an empty featureset for the join with variant
var join_fields = [
{name: "Variant", type: "esriFieldTypeString"}
]
var out_fs = {
geometryType: "",
fields: Splice(Schema(grouped_fs).fields, join_fields),
features: []
}
// join with the original fs to get the variant
for(var f in grouped_fs) {
var d = f.Sample_Date
var s = f.Site_ID
var f = f.Estimated_Frequency_Reads
var join = First(Filter(fs, "Sample_Date = @d AND Site_ID = @s AND Estimated_Frequency_Reads = @f"))
Push(out_fs.features, {attributes:{Sample_Date: Number(d), Site_ID: s, Estimated_Frequency_Reads: f, Variant: join.Variant}})
}
return Featureset(Text(out_fs)) This expression uses Filter() in a loop, which isn't very performant. If the expression is slow, copy the Memorize() function from this blog post and apply it to your Featureset: var fs = Memorize(FeaturesetByPortalItem(...))
... View more
05-17-2023
11:40 AM
|
3
|
0
|
1545
|
|
POST
|
Take a look at the tool documentation, if you haven't done so already. Basically, it's like the normal Calculate Field tool: You define functions in the code block and apply these functions to the fields. For example, here I'm calculating 2 fields at the same time: TextField1 will be a random selection of 2 values TextField2 will contain a string representation of another field I could have gotten the same result by using the normal Calculate Field two times, but this tool is more convenient.
... View more
05-17-2023
10:15 AM
|
1
|
0
|
4319
|
|
POST
|
You have to create a new Featureset and copy the attributes. Luckily, you can do it in a loop, without too much manual work: // define the new field(s)
var new_fields = [
{name: "NewAttribute", type: "esriFieldTypeInteger"},
]
// create an empty featureset with existing and new fields
var out_fs = {
fields: Splice(Schema(layer).fields, new_fields),
geometryType: Schema(layer).geometryType',
features: []
}
// fill the featureset
for (var i in layer) {
var att = {}
// copy existing field values
for(var field in i) {
var value = i[field]
att[field] = IIf(TypeOf(value) == "Date", Number(value), value)
}
// insert the new value(s)
var new_value = 25
att["NewAttribute"] = new_value
// append the feature to the featureset
Push(out_fs.features, {attributes: att, geometry: Geometry(i)})
}
// return
return Featureset(Text(out_fs))
... View more
05-17-2023
09:49 AM
|
2
|
0
|
2493
|
|
POST
|
How do you get the other lines? Do they have a common attribute?
... View more
05-16-2023
01:52 PM
|
0
|
2
|
2571
|
|
POST
|
Also, consider this scenario: A manhole has one inspection and you delete the inspection. As the rule is now, the manhole will keep the inspection values. You might want to set these to null instead of aborting in line 19.
... View more
05-16-2023
01:46 PM
|
1
|
0
|
1507
|
|
POST
|
You assigned this rule to Inspections.Cover_Condition, but you return a GlobalID. My guess is that Cover_Condition has a coded value domain, so it rejects anything not in that domain. Maybe it even is an integer field, so it also can't properly convert the GlobalID (a string) into an integer. I also get confused when writing expressions like this which field I should assign the rule to, or can it be left blank? You can leave the field blank, in that case don't use the "result" keyword. You could also assign your expression as it is to ParentGUID_, because that's the value you return right now. I'm surprised you don't get errors on lines 6 and 11, because you're missing the compare values in the SQL query. Instead of loading the Featureset in line 5, you can just use the $featureset global. $featureset returns the current Featureset, the one this Attribute Rule is assigned to. //Forgein Key in child table
var fk = $feature.ParentGUID_
//Load all inspections of the feature
var related_inspections = Filter($featureset, 'ParentGUID_ = @fk')
//Filter out record if delete trigger
if($editcontext.editType == "DELETE") {
var pk = $feature.GlobalID_1
related_inspections = Filter(related_inspections, "GlobalID_1 <> @pk")
}
//Filter most recent inspection date
var last_inspection = First(OrderBy(related_inspections, "Date_Time DESC"))
//Return nothing if no records found
if(IsEmpty(last_inspection)){
return
}
//Update Cover_Condition field in parent feature class
return {
"edit": [{
"className" : "DBO.ssManhole_z",
"updates": [{
//selecting the parent feature to update
"globalID" : last_inspection.ParentGUID_,
//Update the Cover_Condition field in parent feature class
"attributes" : {
'Cover_Condition': last_inspection.Cover_Condition,
// "Other_Attribute": last_inspection.Other_Attribute,
}
}]
}]
}
... View more
05-16-2023
01:43 PM
|
0
|
2
|
1507
|
|
IDEA
|
I'm just going to collect links to questions where performance was / could have been enhanced by loading Faturesets into RAM here. I will update this once in a while. https://community.esri.com/t5/arcgis-dashboards-questions/dashboard-expression-performance-improvement/m-p/1289760#M7820 https://community.esri.com/t5/arcgis-dashboards-questions/data-expression-with-groupby-and-intersect/m-p/1289174 https://community.esri.com/t5/arcgis-dashboards-questions/how-can-i-improve-performance-of-this-arcade-data/m-p/1354057
... View more
05-16-2023
01:27 PM
|
0
|
0
|
2047
|
|
POST
|
That sounds great! Please also consider kudoing this idea to hopefully have functionality like that in the native Arcade functions one day.
... View more
05-16-2023
01:15 PM
|
0
|
0
|
4063
|
| 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
|