|
POST
|
I think so, yes. Create a memory fc, add the field, insert the current feature (shape and maxheight), run the tool, delet the fc. Depending on your feature count, it might be faster to create the memory fc outside of the loop and truncate instead of delete.
... View more
05-09-2022
01:47 AM
|
0
|
3
|
6086
|
|
POST
|
This is a good use case for Attribute Rules, assuming you don't have to use the feature class in ArcMap (because fc's with Attribute Rules are incompatible with ArcMap). In your case, it's really simple: Add a Constraint Attribute Rule to your feature class set trigger to only "Insert" (and "Delete", if your users aren't allowed to delete features just return false (reject the edit)
... View more
05-08-2022
11:28 PM
|
1
|
0
|
2006
|
|
POST
|
This is the tool's signature and your call: arcpy.conversion.PolygonToRaster(in_features, value_field, out_rasterdataset, {cell_assignment}, {priority_field}, {cellsize}, {build_rat})
arcpy.conversion.PolygonToRaster(fc[0], cellsize, shadowRas, "CELL_CENTER", "NONE", cellsize, "DO_NOT_BUILD") You're using cellsize as value field name. Previously, you assigned the value of MaxHeight to cellsize. In the first feature, the MaxHeight field probably has the value 10, so the tool is trying to access field 10. You should use the actual field name, not the value. Also, not sure, but I think this only works on feature classes, not singular features?
... View more
05-08-2022
10:54 PM
|
1
|
1
|
6215
|
|
POST
|
Ah OK, in that case, you're editing the $feature itself, which makes it a little easier: // calculation attribute rule
// triggers: insert(, update)
// field: GdBOrderNumber
var f_gid = $feature.LocationGlobalID;
var related_records = FeatureSetByName($datastore, "Database.DBO.[FeatureClass]", ["*"], false);
var Join = Filter(related_records, "GlobalID = @f_gid");
// return GdBOrderNumber of the first feature in Join
// if Join is empty (no related features found), return null
var firstJoin = First(Join)
if(firstJoin == null) {
return null
}
return firstJoin.GdBOrderNumber
// or, if you leave the field parameter empty:
return {
"result": {"attributes": {"GdBOrderNumber": firstJoin.GdBOrderNumber}}
}
... View more
05-08-2022
10:41 PM
|
1
|
1
|
1637
|
|
POST
|
Oh, my answer checks if there are any features in intersectLayer1. If you want to check for null values in Field, you can do that like this: // returns the value of the first non-empty field "Field"
for(var f in intersectLayer1) {
if(!IsEmpty(f.Field)) {
return f.Field
}
}
for(var f in intersectLayer2) {
if(!IsEmpty(f.Field)) {
return f.Field
}
}
return "nothing found"
... View more
05-04-2022
10:25 PM
|
1
|
1
|
2482
|
|
POST
|
var featureLayer1 = First(intersectLayer1)
var featureLayer2 = First(intersectLayer2)
if(featureLayer1 != null) {
return featureLayer1.Field
}
if(featureLayer2 != null) {
return featureLayer2.Field
}
return "nothing found" or (same output, a little shorter) for(var f in intersectLayer1) {
return f.Field
}
for(var f in intersectLayer2) {
return f.Field
}
return "nothing found"
... View more
05-04-2022
10:21 PM
|
1
|
0
|
2492
|
|
POST
|
Include a null check in the conditions: if(i_geom == null || i_geom.type != "Point" ||
Equals(i_geom, Geometry(i_line).paths[0][0] ||
Equals(i_geom, Geometry(i_line).paths[-1][-1] ) {
continue
}
... View more
05-04-2022
09:53 PM
|
0
|
0
|
1204
|
|
POST
|
You can use the arcpy.sa.Raster class, which has a built-in raster cell iterator: def get_raster_areas(raster_path, upper_bounds):
"""Returns the areas of a raster that are below the given values.
raster_path: str, path to the raster
upper_bounds: [float], the upper bounds of your desired value bins
"""
# get raster object
raster = arcpy.sa.Raster(raster_path)
# get cell area
dimensions = raster.getRasterInfo().getCellSize()
cell_area = dimensions[0] * dimensions[1]
# initialize the area list
upper_bounds.sort() # it's important that upper_bounds is sorted
areas = [0 for x in upper_bounds]
# loop over the raster cells
for row, col in raster:
# loop over the upper_bounds
for i, ub in enumerate(upper_bounds):
# if raster cell value is below upper bound,
# add cell_area to the corresponding element in the areas list
# and break, so this cell doesn't also get added to the other (higher) bins
# (that's why we needed to make sure upper_bounds is sorted)
if raster[row, col] < ub:
areas[i] += cell_area
break
# return the area list
return areas
rp = r"G:\...\DGM1_2017_HB1.TIF" # 100x100m raster of elevations in a coastal town
bins = [0, 8, 12, 15]
areas = get_raster_areas(rp, bins)
for b in range(len(bins)):
print(f"elevation < {bins[b]}m: {areas[b]}m²")
#elevation < 0m: 33.0m² # below 0m
#elevation < 8m: 997968.0m² # between 0m and 8m
#elevation < 12m: 0m² # between 8m and 12m
#elevation < 15m: 0m² # between 12m and 15m
... View more
05-04-2022
02:21 AM
|
1
|
1
|
2399
|
|
POST
|
# load the power lines (geometry and year_installed)
power_lines = [row for row in arcpy.da.SearchCursor("path:/to/powerlines", ["SHAPE@", "year_installed"])]
# open an UpdateCursor on the lights with NULL values
with arcpy.da.UpdateCursor("path:/to/lights", ["SHAPE@", "year_installed"], "year_installed IS NULL") as cursor:
for shp, year in cursor:
# sort the power lines by distance to shp
power_lines.sort(key=lambda pl: pl[0].distanceTo(shp))
# use the closest power line's year value
cursor.updateRow([shp, power_lines[0][1]])
... View more
05-03-2022
11:59 PM
|
3
|
1
|
1580
|
|
POST
|
I haven't worked with GetUser() yet, but you should be able to do something like this var user = GetUser($featureSet)
if(!IsEmpty(user)) {
user = user.username
} In your FGDB, you won't have success with this, because When no user is associated with the workspace, such as a file geodatabase, an empty string will be returned. You could try turning on Editor Tracking, and then use the last_edited_user field: var user = $feature.last_edited_user
... View more
05-03-2022
11:47 PM
|
1
|
0
|
2354
|
|
POST
|
It should be possible. Something like this (completely untested!) // Calculation Attribute Rule on LineFC
// Field: empty
// triggers: insert(, update)
// load the whole LineFC
var line_fs = FeatureSetByNAme($datastore, "LineFC", ["GlobalID"], true)
// get the intersecting lines
var intersect_lines = Intersects(line_fs, $feature)
// create and fill adds and deletes arrays
var adds = []
var deletes = []
for(var i_line in intersect_lines) {
// get intersection geometry
var i_geom = Intersection(i_line, $feature)
// there are multiple conditions where we don't want to cut the line:
// intersection isn't a point (overlapping lines or i_line == $feature)
// i_line is intersecting $feature on start or end point
if(i_geom.type != "Point" ||
Equals(i_geom, Geometry(i_line).paths[0][0] ||
Equals(i_geom, Geometry(i_line).paths[-1][-1] ) {
continue
}
// cut i_line with $feature, delete the original, add the cut parts
var cut_parts = Cut(i_line, $feature)
Push(deletes, {"globalID": i_line.GlobalID})
for(var p in cut_parts) {
Push(adds, {"geometry": cut_parts[p]})
}
}
// apply the edits
return {
"edit": [
{
"className": "LineFC",
"adds": adds,
"deletes": deletes
}
]
}
... View more
05-03-2022
11:32 PM
|
0
|
0
|
1228
|
|
POST
|
So, you have Table A with this rule and you want to populate the field "GdBOrderNumber" on Table B, is that correct? // calculation attribute rule
// triggers: insert(, update)
// field: empty
// get the related record(s)
// either use FeatureSetByName() and Filter() like you did
// or use the relationship class:
var related_records = FeatureSetByRelationshipName($feature, "RelationShipName", ["GlobalID"], false)
// we're only interested in the related records' GlobalID, because we need that to identify them in the return dictionary
// create and fill the update array
var updates = []
for(var record in related_records) {
// updates is an array of dictionaries
// the dictionaries are built like this:
// {"globalID": "GID of the edited feature", "attributes": {"Field": value}}
var update = {"globalID": record.GlobalID, "attributes": {"GdBOrderNumber": $feature.GdBOrderNumber}}
Push(updates, update)
}
// apply the edits
return {
"edit": [
{
"className": "Database.DBO.OtherTable",
"updates": updates
}
]
} To learn more about the return dictionary keywords, read this: Attribute rule dictionary keywords—ArcGIS Pro | Documentation
... View more
05-03-2022
07:06 AM
|
0
|
4
|
1703
|
|
POST
|
Wait, wait, wait! This solution is much better. Cleaner, less work, and you don't have to round: create and upload the full 100% gauge use the HTML and Arcade expression below This makes use of the relative and absolute positioning in CSS. Basically, you can tell an element where exactly it shall be placed (absolute) inside its parent element. This only works if the parent's positioning is relative. So we make the <td>s relative, show the full gauge and overlay that with an absolutely positioned <div> that has the same background color as the table. <table style="background: white;">
<tr>
<td>US-Born</td>
<td style="position: relative;">
<img src="https://.../gauge.png">
<div style="{expression/expr0}"></div>
</td>
</tr>
<tr>
<td>Foreign-Born</td>
<td style="position: relative;">
<img src="https://.../gauge.png">
<div style="{expression/expr1}"></div>
</td>
</tr>
</table> // expr0, others analogous
// calculate percentage
// ... your code here ...
var percentage = 68
// return the styling of the blocking bar
// absolute positioning at the right of the parent element
// left border is at (percentage)% of the parent element's width
// background is the same color as the table's
return "position: absolute; top: 0; bottom: 0; right: 0; left: " + percentage + "%; background: white"
... View more
05-03-2022
05:36 AM
|
1
|
0
|
4285
|
|
POST
|
So, ideally you would have the icon url and one expression for each parameter that returns repeated <img> tags. This is not possible, yet, ArcGIS wouldn't interpret the HTML but show it as plain text. As I see it, the cleanest solution is this: create and upload separate images for all possible gauges (10 if you want to round to the next 10, 20 if you want to round to the next 5 like in your example) ideally, use the same width In your popup's HTML source, use <img> tags like in the example below For each gauge, you need an expression to return the right image url <table>
<tr>
<td>US-Born</td>
<td><img src="{expression/expr0}"></td>
</tr>
<tr>
<td>Foreign-Born</td>
<td><img src="{expression/expr1}"></td>
</tr>
...
<tr>
<td>$35,000+</td>
<td><img src="{expression/expr5}"></td>
</tr>
</table> // expr0, others analogous
// calculate your percentage value
// ... your code here ...
var percentage = 38.28
// round your percentage to the next 10 (5 would be analogous)
var round_percentage = Round(percentage / 10) * 10
// define a dictionary to link rounded percentages to the gauge images
var url_dict = {
"0": "https://.../gauge_0.png",
"10": "https://.../gauge_10.png",
// ...
"100": "https://.../gauge_100.png"
}
// return the appropriate image url
return url_dict[Text(round_percentage)]
... View more
05-03-2022
04:52 AM
|
0
|
0
|
4285
|
| 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
|