|
POST
|
Yep. Inputting the values through the Active Template pane is sensible if you need new features to have an attribute, eg because you need it in an Attribute Rule that triggers on insert. If you don't need that functionality, the Attribute pane is the way to go.
... View more
05-24-2023
06:27 AM
|
0
|
0
|
1898
|
|
POST
|
Oh right. this calculation is for cartesian coordinate systems, as per your question. I have only worked with projected coordinate systems until now, so I'm not really sure how this will play out in a geographical coordinate system. The error might be negligible over small distances, but for greater distances, it will probably become apparent. Maybe you can get away with converting the points into a locally applicable projected coordinate system, do the calculation, and then project the resulting points into the geographic system.
... View more
05-24-2023
06:16 AM
|
0
|
0
|
4619
|
|
POST
|
PS: This problem has two solutions, depending on which diagonal the two point describe. If you change line 26 to take the arctan of 1/aspect, you get the second solution. Left: solution 1 -> atan(aspect), Right: solution 2 -> atan(1/aspect)
... View more
05-24-2023
12:09 AM
|
0
|
0
|
4631
|
|
POST
|
Hey Helen, this will probably need a bit of Python. Just to be clear: What type of "merge" are you talking about? Let's say we have two overlapping polygons in 2 layers: Is your desired output the result of the Merge geoprocessing tool? This will combine multiple tables, each row of each table will be copied without editing. (Selection to show that they still overlap) Or do you want the result of the geoprocessing tool Union? This works similar to Merge, but it creates the intersections as extra polygons. (Selection to show that the original polygons have been edited) Or do you want the result of the editing tool Merge? This takes 2 geometries and turns them into one. Or do you want something else?
... View more
05-23-2023
11:59 PM
|
0
|
0
|
1157
|
|
POST
|
Am I overthinking this to much in a big way? Can I do the calculations with simple trigonometry instead of GeoemtryEngine methods? Probably. I don't know anything about the .Net SDK, but here is what you could do in pure Python (without using the arcpy geometry methods): import math
# some basic trigonometry functions
# points as coordinate tuples
# angles in radians
def distance(p1, p2):
return math.sqrt(math.pow(p1[0] - p2[0], 2) + math.pow(p1[1] - p2[1], 2))
def angle(p1, p2):
return math.atan2(p2[1] - p1[1], p2[0] - p1[0])
def point_from_angle_and_distance(p, a, d):
return (p[0] + d * math.cos(a), p[1] + d * math.sin(a))
def get_rectangle(p1, p2, aspect):
""" Outputs the vertices of the (a) rectangle defined by the two given corner points and the aspect ratio.
p1, p2: Coordinate tuples of two points in a diagonal of the rectangle
aspect: ratio of the two sites (<= 1)
"""
# get the center of the diagonal
a_p1p2 = angle(p1, p2)
d_p1p2 = distance(p1, p2)
center = point_from_angle_and_distance(p1, a_p1p2, d_p1p2 / 2)
# convert the aspect ratio to angle between the diagonals
a_diag = math.pi - 2 * math.atan(aspect)
# get the other two points
p3 = point_from_angle_and_distance(center, a_p1p2 - a_diag, d_p1p2 / 2)
p4 = point_from_angle_and_distance(center, a_p1p2 + math.pi - a_diag, d_p1p2 / 2)
# reorder and return
return [p1, p3, p2, p4] Now let's give that method a spin... We will read from a Multipoint layer, convert the multipoints to coordinate tuples, calculate the resulting rectangle for multiple aspect ratios, convert those rectangles into arcpy.Polygons and write them into a polygon layer. aspect_ratios = [0.01, 0.25, 0.5, 0.75, 1]
with arcpy.da.InsertCursor("TestPolygons", ["SHAPE@", "DoubleField1"]) as i_cursor:
with arcpy.da.SearchCursor("TestMultipoints", ["SHAPE@"]) as s_cursor:
for shp, in s_cursor:
p1 = (shp.firstPoint.X, shp.firstPoint.Y)
p2 = (shp.lastPoint.X, shp.lastPoint.Y)
for aspect in aspect_ratios:
rect_points = get_rectangle(p1, p2, aspect)
vertices = [arcpy.Point(p[0], p[1]) for p in rect_points]
poly = arcpy.Polygon(arcpy.Array(vertices), spatial_reference=arcpy.SpatialReference(25833))
i_cursor.insertRow([poly, aspect]) Result: So yeah, you just need basic trigonometry for this.
... View more
05-23-2023
03:17 PM
|
0
|
1
|
4659
|
|
POST
|
Your braces in lines 11 & 12 are wrong, you have your id field outside of the attributes. Push(recalc.features, {attributes: {memberName: member, id: f.OBJECTID}})
... View more
05-23-2023
12:14 PM
|
0
|
0
|
2154
|
|
POST
|
var value_counts = {
"Always Off": 0,
"Tree Obstruction": 0,
}
var fields = ["Status1", "Status2", "Status3"]
var p = Portal(...)
var fs = FeaturesetByPortalItem(p, id, layer, fields, false)
for(var f in fs) {
for(var i in fields) {
var value = f[fields[i]]
if(IsEmpty(value)) { continue }
if(!HasKey(value_count, value)) { value_counts[value] = 0 }
value_counts[value] = value_counts[value] + 1
}
}
var out_fs = {
geometryType: "",
fields: [
{name: "Status", type: "esriFieldTypeString"},
{name: "Count", type: "esriFieldTypeInteger"},
],
features: []
}
for(var value in value_counts) {
var c = value_counts[value]
var f = {attributes: {Status: value, Count: c}}
Push(out_fs.features, f)
}
return Featureset(Text(out_fs))
... View more
05-23-2023
12:10 PM
|
2
|
1
|
6320
|
|
POST
|
You're trying to access the field "county" from the Featureset (fs). This isn't possible, you have to do it with the Feature (f) Your condition is wrong. The OR operator ( || ) combines multiple "standalone" expressions, each one has to be able to be evaluated. You want something like this: f["county"] == "Carbon" || f["county"] == "Beaver || f["county"] == "Box Elder" This isn't very fun to write, but that's what the Includes() function is for: IIf(Includes(["County 1", "County 2", "County 3"], f["county"], ...) Instead of nesting these IIf(), use When(). for(var f in fs) {
var c = f["county"]
var member = When(
Includes(["C1", "C2", "C3"], c), "Member1",
Includes(["C4", "C5", "C6"], c), "Member2",
Includes(["C7", "C8"], c), "Member3",
"Not assigned to any member"
)
Push(recalc.features, {attributes: {memberName: member}})
}
... View more
05-23-2023
11:51 AM
|
0
|
2
|
2162
|
|
POST
|
Python: #YourField =
calc(!OBJECTID!)
#Code Block
last_val = None
def calc(val):
global last_val
diff = (val - last_val) if last_val is not None else None
last_val = val
return diff Arcade var oid = $feature.OBJECTID
var last_row = First(OrderBy(Filter($featureset, "OBJECTID < @oid"), "OBJECTID DESC"))
if(last_row == null) { return null }
return $feature.OBJECTID - last_row.OBJECTID
... View more
05-23-2023
11:40 AM
|
1
|
1
|
1283
|
|
POST
|
Getting the same behaviour for point features that are somewhere in between start- or endpoint For that, you replace the rule on the point fc with this: function split_polyline_into_segments(polyline_geometry) {
// takes the polyline_geometry and splits it into segments (Polylines that have only 2 vertices)
// returns an array of those segments
var sr = polyline_geometry.spatialReference
var vertices = polyline_geometry.paths[0]
var segments = []
for(var s=0; s<Count(vertices)-1; s++) {
var p0 = vertices[s]
var p1 = vertices[s+1]
Push(segments, Polyline({"paths": [[ [p0.x, p0.y, p0.z, p0.m], [p1.x, p1.y, p1.z, p1.m] ]], "spatialReference": sr}))
}
return segments
}
function project_orthogonally(point_geometry, line_geometry) {
// returns a projection of the point_geometry onto the line_geometry
// only start and end point of the line_geometry are considered!
// the projection is done in 2D, the returned point_geometry has the same Z and M values as the input.
// https://de.wikipedia.org/wiki/Orthogonalprojektion
// https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line
if(line_geometry == null) { return point_geometry }
var p = point_geometry
var r0 = line_geometry.paths[0][0]
var r1 = line_geometry.paths[0][-1]
var ux = r1.x - r0.x
var uy = r1.y - r0.y
var lambda = ((p.x-r0.x)*ux + (p.y-r0.y)*uy) / (ux*ux + uy*uy)
var new_p = Point({x: r0.x + lambda * ux, y: r0.y + lambda * uy, spatialReference: p.spatialReference})
// if new_p is on the line defined by r0 and r1 but not on the actual line_geometry, snap it to the closest end point
if(Disjoint(new_p, line_geometry)) {
new_p = IIF(Distance(r0, p) < Distance(r1, p), r0, r1)
}
// add z and m value
new_p = Point({x: new_p.x, y: new_p.y, z: p.z, m: p.m, spatialReference: p.spatialReference})
return new_p
}
// get first line feature in a small radius
var lines = FeaturesetByName($datastore, "TestLinesMZ", ["GlobalID"], true)
var i_line = First(Intersects(lines, Buffer($feature, 1, "meters")))
if(i_line == null) { return }
// split i_line into line segments (only 2 vertices)
var segments = split_polyline_into_segments(Geometry(i_line))
// get the line segment closest to $feature
function sort_by_distance_to_feature(s1, s2) {
return Distance(s1, $feature) > Distance(s2, $feature)
}
var closest_segment = Sort(segments, sort_by_distance_to_feature)[0]
// project point onto that segment
var sp = project_orthogonally(Geometry($feature), closest_segment)
// add vertex to the segment
// the segment has 2 vertices
// if point is on an end point, add vertext at end of line segment, else in the middle
var new_path = [closest_segment.paths[0][0], closest_segment.paths[0][-1]]
var i = When(
Intersects(sp, new_path[0]), 0,
Intersects(sp, new_path[1]), 2,
1)
Insert(new_path, i, [sp.x, sp.y, sp.z, sp.m])
var new_segment = Polyline({paths: [new_path], spatialReference: closest_segment.spatialReference})
// replace the old line segment
var i = IndexOf(segments, closest_segment)
segments[i] = new_segment
// create the new Polyline
var new_line = Union(segments)
return {
result: {geometry: sp},
edit: [{
className: "TestLinesMZ",
updates: [{
globalID: i_line.GlobalID,
geometry: new_line
}]
}]
} Old line Adding a point somewhere in the middle Adding a point before the start point
... View more
05-23-2023
05:46 AM
|
0
|
0
|
2846
|
|
POST
|
Instead of converting to Shapefile and referencing that, do it the other way around: Load your CAD file, this will be inserted as a group layer. Select on of the actual layers (eg Multipatch) to activate the CAD-Data ribbon You can now georeference the CAD file like you would do with imagery. When you're done, you can export to the format of your choice. https://pro.arcgis.com/en/pro-app/3.0/help/data/cad/georeferencing-cad-data.htm
... View more
05-23-2023
03:05 AM
|
0
|
0
|
3799
|
|
POST
|
OK, so something like this should work (replace fc name in lines 7 & 32): // Calculation Attribute Rule on Z-enabled Point fc
// field: empty
// triggers: insert
// get first line feature in a small radius
var lines = FeaturesetByName($datastore, "TestLinesMZ", ["GlobalID"], true)
var i_line = First(Intersects(lines, Buffer($feature, 1, "meters")))
if(i_line == null) { return }
// get distances from start and end point
var line_geo = Geometry(i_line)
var point_geo = Geometry($feature)
var d_start = Distance(point_geo, line_geo.paths[0][0])
var d_end = Distance(point_geo, line_geo.paths[-1][-1])
// get the new point coordinates: x/y from the closest line end point, z from the point
var i = IIf(d_start < d_end, 0, -1)
var v = [line_geo.paths[i][i].x, line_geo.paths[i][i].y, point_geo.z, null]
// snap the point to start or end of line
var new_point_geo = {x: v[0], y: v[1], z: v[2], m: v[3], spatialReference: point_geo.SpatialReference}
// add vertex at start or end of line
var new_line_geo = Dictionary(Text(line_geo))
var j = IIf(i == 0, 0, Count(new_line_geo.paths[0]))
Insert(new_line_geo.paths[0], j, v)
return {
result: { geometry: Point(new_point_geo) },
edit: [{
className: "TestLinesMZ",
updates: [{
globalID: i_line.GlobalID,
geometry: Polyline(new_line_geo)
}]
}]
} Old line Insert a point near the end of the line, set its Z value Add another point near the start of the line
... View more
05-23-2023
02:45 AM
|
0
|
0
|
2855
|
|
POST
|
You can't use Arcade to reset the sequence, but you can do it without a sequence: // Calculation Attribute Rule
// field: FacilityID
// triggers: insert
// get the feature that was created last
var fs = Filter($featureset, "FacilityID IS NOT NULL")
var last_f = First(OrderBy(fs, "OBJECTID DESC"))
if(last_f == null) { return $feature.FaciltyID }
// get its sequence value
var old_seq = Number(Split(last_f.FacilityID, "_")[-1])
// get the new sequence value
var new_seq = IIf(old_seq + 1 > 999999, 1, old_seq + 1)
// construct and return the new FacilityID
var s = Text(new_seq, "000000")
var d = Text(Today(), "DDMMY")
return `ABC_${d}_${s}`
... View more
05-22-2023
02:25 PM
|
1
|
0
|
1172
|
|
POST
|
calculate the 3D length of line features Length3D() does that. add a vertex to the line exactly where the point feature is located in terms of x and y-coordinates, but with the same height as the line feature Not trivial, but doable. You'd have to project the point onto the line(in 2D, I have some code for that here), interpolate the height at that point, then insert a new vertex with the point feature's x/y coordinates and the calculated height. I don't understand these two requests: the line feature - after adding the point feature- should have a "L"-Shape extending the line feature in a right angle to the point feature the point feature should become the new end/or start vertex of the line feature while still maintaining its height. The first request sounds like you want something like this (black: original line, blue: point feature, red: edited line, 2D): The second request sounds like you want to either split the line at the new vertex or to snap the point to a line end or something completely else. Could you explain more clearly, maybe supply a sketch?
... View more
05-22-2023
09:06 AM
|
1
|
1
|
2868
|
| 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
|