POST
|
Is there some settings file that tells it where to open the application? For Windows OS, a window normally opens at the position where you last closed it. My cursor cannot get beyond the right edge of my screen to move it back, though, so I literally have no way of getting the application back into my view to interact with it. Try moving it with your keyboard. Windows: ALT+SPACE opens a small menu, then press M (for Move). You should then be able to move the application window with the arrow keys.
... View more
12-05-2023
10:09 AM
|
4
|
2
|
2449
|
POST
|
Yeah, it's an attribute, not a method, my bad. SHAPE@XY should give the centroid, too, but only as coordinates, so you would probably have to construct the point geometry.
... View more
12-05-2023
10:00 AM
|
0
|
0
|
1267
|
POST
|
Yeah, that one's on me... centroid is an attribute, not a method (I had the parentheses after centroid. I fixed it in my test code, but not here...) Should be fixed, try it again, please.
... View more
12-05-2023
09:56 AM
|
0
|
1
|
1267
|
POST
|
// Calculation Attribute Rule in the point fc
// field: empty
// triggers: insert
// exclude from application evaluation
var parks_fc = FeaturesetByName($datastore, "ParksFC")
var parks_table = FeaturesetByName($datastore, "ParksTable")
var park_polygon
// get the park polygon
// by filtering for the park_name attribute
if(!IsEmpty($feature.park_name)) {
var p_name = $feature.park_name
park_polygon = First(Filter(parks_fc, "park_name = @p_name"))
}
// or by intersecting the bench with the parks fc
if(park_polygon == null) {
park_polygon = First(Intersects($feature, parks_fc))
}
if(park_polygon == null) { return } // we couldn't find a corresponding park polygon, abort
// get the related table row
var key = park_polygon.KeyField
var park_row = First(Filter(parks_table, "KeyField = @Key"))
if(park_row == null) { return } // the polygon doesn't have a corresponding table row, abort
// return a dictionary to instruct ArcGIS to update the park table
return {
// result: attributes: {park_name: park_polygon.park_name}}, // set the bench's park_name field
edit: [{
className: "ParksTable",
updates: [{
objectID: park_row.OBJECTID,
attributes: {HasBenches: "Yes"}
}]
}]
} Edit lines 6, 7, 12-14, 23, 24, 32, 35 to fit your table and field names. Further reading for the return dictionary: https://pro.arcgis.com/en/pro-app/latest/help/data/geodatabases/overview/attribute-rule-dictionary-keywords.htm
... View more
12-04-2023
10:07 AM
|
0
|
1
|
350
|
POST
|
This is an expression for a Calculation Attribute Rule with the field parameter left empty (it returns a dictionary). If you want to use this in other ways (eg a popup or an Attribute Rule with a set field), you should return a single value. Have you tried to return intersected_feature.NAME instead of intersected_feature[intersecting_field]?
... View more
12-04-2023
09:31 AM
|
0
|
1
|
777
|
POST
|
Copy/paste this script into the Python window, edit the first 5 lines, run it (this edits your feature class, make a backup!) polygons = "TestPolygons" # name of the polygon layer / path to the fc
points = "TestPoints" # name of the point layer / path to the fc
poly_field = "IntegerField1" # name of the common field in the polygon fc
point_field = "IntegerField1" # name of the common field in the point fc
do_all = False # False: only non-intersecting points are moved. True: all points are moved to the centroid
# read the polygons into a dictionary {CommonField: Geometry}
poly_shapes = dict([row for row in arcpy.da.SearchCursor(polygons, [poly_field, "SHAPE@"])])
# Start editing the point fc
with arcpy.da.UpdateCursor(points, [point_field, "SHAPE@"]) as cursor:
for key, shp in cursor:
try:
# get the corresponding polygon
poly_shp = poly_shapes[key]
# check if the point has to be moved
if do_all or shp.disjoint(poly_shp):
try:
# set the point's geometry to the polygon's centroid
cursor.updateRow([key, poly_shp.centroid])
except:
print(f"Couldn't get the centroid of {key}, sklipping")
except KeyError:
print(f"No polygon found for {key}, skipping") Before: With do_all = False With do_all = True
... View more
12-02-2023
07:53 AM
|
4
|
6
|
1365
|
POST
|
Arcade is built to optimize queries to the server where the actual data is stored. So when you call FeaturesetByPortalItem(), the fs isn't actually loaded into your local RAM, it just creates a connection to the fs on the server. This is done to then optimize Filter(), Intersects(), First() and so on to send as few as possible query requests to the server. This approach doesn't work with calling these functions in a loop. You're basically bombarding the server with hundreds to thousands filter requests (one for each feature in the fs), which slows the script down to a crawl. The developers are aware of this, but I wouldn't hold my breath waiting for a solution, it's basically a known limitation at this point. The intended approach is to use a joined layer. But using a joined layer isn't always possible or sensible. For these cases, @jcarlson wrote a nifty function that actually loads the fs into your local RAM, where repeated Filter() calls are much faster: Improving Expression Performance: A Custom Function In your case, we don't actually need that function, but the principle still applies: Copy the data from the server and do your filtering locally. In this case, we can use a simple dictionary (lines 21, 22, 34): // only load the fields you need
var portal = Portal("https://www.arcgis.com/");
var polyfs = FeatureSetByPortalItem(
portal,
"4dbbad3d6f694e0ebc7c3b4132ea34df",
0,
["HydroID", "DPS_Region"],
false
);
var tablefs = FeatureSetByPortalItem(
portal,
"4dbbad3d6f694e0ebc7c3b4132ea34df",
6,
["FeatureID", "ModelID", "AddressCount", "MAX_TSTime"],
false
);
// repeatedly sending Filter requests to the server slows the script down to a crawl for larger Featuresets.
// It's best to create a copy in local RAM. In this case, we can just use a dictionary {HydroID: DPS_Region}.
// If you need Filter(), use the Memorize() function defined in the blog post above.
var dps_regions = Dictionary()
for(var p in polyfs) { dps_regions[Text(p.HydroID)] = p.DPS_Region }
// Create empty features array and feat object
var features = [];
var feat;
// Populate Feature Array
for (var t in tablefs) {
var tableID = Text(t["FeatureID"])
feat = {
attributes: {
FeatureID: tableID,
Name: dps_regions[tableID],
ModelID: t["ModelID"],
AddressCount: t["AddressCount"],
MAX_TSTime: t["MAX_TSTime"],
}
}
Push(features, feat)
}
var joinedDict = {
fields: [
{ name: "FeatureID", type: "esriFieldTypeString" },
{ name: "Name", type: "esriFieldTypeString" },
{ name: "ModelID", type: "esriFieldTypeInteger" },
{ name: "AddressCount", type: "esriFieldTypeInteger" },
{ name: "MAX_TSTime", type: "esriFieldTypeString" },
],
'geometryType': '',
'features':features
};
// Return dictionary cast as a feature set
return FeatureSet(joinedDict); This script executes more than 2 times faster than your original script. I expect it will be even more noticeable for large Featuresets. Take a look at these related Ideas and maybe lend your support. Hopefully, they will be implemented someday... Arcade FeatureSet Functions should have the option to output to RAM Arcade: Add a function that quickly converts a Featureset into an Array Arcade: Add Function to Join Featuresets Arcade: Add a function to merge multiple Featuresets
... View more
11-26-2023
03:19 AM
|
2
|
1
|
958
|
POST
|
Is this always the case or is there a way to make it so the shape length field automatically calculates and shows the feature length? The Shape_Length field always shows the polygon's perimeter. Most areas represented by polygons are not regular shapes like rectangles, where the concepts of "length" and "width" make sense. They are mostly irregular, so the perimeter is the only sensible choice for Shape_Length. If you want to calculate "Length" as "The longest side of this polygon", you can do it with code in Calculate Field. Arcade (copied from my answer here😞 var distances = []
// get the polygon parts
var rings = Geometry($feature).rings
// loop over the parts
for(var r in rings) {
var ring = rings[r]
// loop over the vertices (skip first)
for(var v = 1; v < Count(ring); v++) {
Push(distances, Distance(ring[v - 1], ring[v]))
}
}
return Max(distances) Python: # LengthField =
get_longest_side(!Shape!)
# Code Block
def get_longest_side(polygon):
sr = polygon.spatialReference
distances = []
for p in range(polygon.partCount):
ring = polygon.getPart(p)
for i in range(1, len(ring)):
c1 = ring.getObject(i-1)
p1 = arcpy.PointGeometry(arcpy.Point(c1.X, c1.Y, c1.Z), spatial_reference=sr)
c2 = ring.getObject(i)
p2 = arcpy.PointGeometry(arcpy.Point(c2.X, c2.Y, c2.Z), spatial_reference=sr)
distances.append(p1.distanceTo(p2))
return max(distances) You can also do it in the Python Window: with arcpy.da.UpdateCursor("TestPolygons", ["SHAPE@", "DoubleField1"]) as cursor:
for polygon, length in cursor:
sr = polygon.spatialReference
distances = []
for ring in polygon:
for i in range(1, len(ring)):
p1 = arcpy.PointGeometry(arcpy.Point(ring[i-1].X, ring[i-1].Y, ring[i-1].Z))
p2 = arcpy.PointGeometry(arcpy.Point(ring[i].X, ring[i].Y, ring[i].Z))
distances.append(p1.distanceTo(p2))
cursor.updateRow([polygon, max(distances)])
... View more
11-11-2023
08:24 AM
|
3
|
0
|
1083
|
POST
|
@m3 It doesn't work with labels, only with symbology (but I guess you're actually using symbology) It doesn't work with attachments. You have to read the byte data into the actual table.
... View more
11-11-2023
07:28 AM
|
0
|
1
|
400
|
POST
|
Filters are supported for field parameters, but only for field types. Field types can be found here: https://pro.arcgis.com/en/pro-app/latest/arcpy/classes/field.htm So for example, to only show numerical fields: def getParameterInfo(self):
p0 = arcpy.Parameter(name="layer", displayName="Layer", datatype="GPFeatureLayer")
p1 = arcpy.Parameter(name="field", displayName="Field", datatype="Field"),
p1.parameterDependencies = ["layer"]
p1.filter.list = ["integer", "single", "double"]
return [p0, p1] This sadly doesn't help with excluding specific field names, but maybe it's enough for your use case.
... View more
10-06-2023
02:49 AM
|
1
|
0
|
683
|
POST
|
Seeing as it's not documented, I'd wager it's not something that users are meant to interact with. Might be an oversight/bug. Just get the arcpy._mp.Layer object from the map using the MappingLayerObject.name property and do your CIM manipulations like normal.
... View more
10-06-2023
02:22 AM
|
0
|
1
|
809
|
POST
|
Hmm... Difficult to say what's wrong without the actual data. Would it be possible to send me an extract of your data? Either here or in a pm.
... View more
10-06-2023
02:14 AM
|
0
|
0
|
800
|
POST
|
Interesting... Just a quick test: # -*- coding: utf-8 -*-
import arcpy
import json
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = "toolbox"
# List of tool classes associated with this toolbox
self.tools = [Tool]
def msg(txt=""):
arcpy.AddMessage(str(txt))
class Tool(object):
def __init__(self):
self.label = "Tool"
def getParameterInfo(self):
return [
arcpy.Parameter(name="p0", displayName="Layer", datatype="GPFeatureLayer"),
arcpy.Parameter(name="p1", displayName="Layer Multi", datatype="GPFeatureLayer", multiValue=True),
]
def execute(self, parameters, messages):
# print parameter types
for p in parameters:
msg(f"parameter name: {p.displayName}")
msg(f"\tparameter value: {p.value}")
msg(f"\tvalue type: {type(p.value)}")
if p.multiValue:
msg(f"\ttype of first value: {type(p.value.GetTrueValue(0,0))}")
# get the actual arcpy.mp.Layer object
mapping_layer = parameters[0].value
layer = arcpy.mp.ArcGISProject("current").activeMap.listLayers(mapping_layer.name)[0]
# examine similarities and differences between arcpy.mp.Layer and MappingLayerObject
l_dir = set(dir(layer))
ml_dir = set(dir(mapping_layer))
msg("Available in both:")
for a in sorted(l_dir.intersection(ml_dir)):
msg(f"\t{a}")
msg("Not available in MappingLayerObject:")
for a in sorted(l_dir - ml_dir):
msg(f"\t{a}")
msg("Not available in arcpy.mp.Layer:")
for a in sorted(ml_dir - l_dir):
msg(f"\t{a}")
# get the MappingLayerObject's CIM
d = json.loads(mapping_layer.GetCimJSONString())
msg("GetCimJSONString keys:")
for k in sorted(d.keys()):
msg(f"\t{k}")
# try playing with it (doesn't work)
d["visibility"] = False
mapping_layer.SetCimJSONString(json.dumps(d))
# try manipulating the cim (this works)
cim = layer.getDefinition("V3")
cim.visibility = False
layer.setDefinition(cim) parameter name: Layer parameter value: <MappingLayerObject object at 0x0000020F36A80F60> value type: <class 'MappingLayerObject'> parameter name: Layer Multi parameter value: TestPoints value type: <class 'geoprocessing value table object'> type of first value: <class 'MappingLayerObject'> Available in both: URI __class__ __delattr__ __dir__ __doc__ __eq__ __format__ __ge__ __getattribute__ __gt__ __hash__ __init__ __init_subclass__ __le__ __lt__ __ne__ __new__ __reduce__ __reduce_ex__ __repr__ __setattr__ __sizeof__ __str__ __subclasshook__ brightness connectionProperties contrast dataSource definitionQuery disableTime enableTime extrusion getSelectionSet is3DLayer isBasemapLayer isBroken isFeatureLayer isGroupLayer isNetworkAnalystLayer isNetworkDatasetLayer isRasterLayer isSceneLayer isTimeEnabled isWebLayer listDefinitionQueries listLabelClasses listLayers listTables longName maxThreshold metadata minThreshold name saveACopy setSelectionSet showLabels supports symbology time transparency updateConnectionProperties updateDefinitionQueries visible Not available in MappingLayerObject: __dict__ __from_scripting_arc_object__ __module__ __weakref__ _arc_object getDefinition setDefinition updateLayerFromJSON Not available in arcpy.mp.Layer: GetCimJSONString SetCimJSONString UpdateLayerFromJSON _XML _id _pUnk isLayerSame GetCimJSONString keys: allowDrapingOnIntegratedMesh autoGenerateFeatureTemplates blendingMode description displayCacheType displayFiltersType enableDisplayFilters expanded featureBlendingMode featureCacheType featureElevationExpression featureTable featureTemplates htmlPopupEnabled labelClasses layerElevation layerType maxDisplayCacheAge metadataURI name popupInfo refreshRate refreshRateUnit renderer scaleSymbols selectable serviceLayerID showLegends showPopups snappable sourceModifiedTime symbolLayerDrawing type uRI useSourceMetadata visibility multiValue doesn't seem to be the culprit. The single parameter value is a MappingLayerObject, too. they have many similarities to "normal" layers. The significant differences: the way to access the cim properties (Python objects vs JSON) MappingObjectLayer doesn't seem to be derived from an arcobject (it doesn't have the _arcobject property). Most arcpy classes are just wrappers around ArcObjects, MappingLayerObject might be different. I did not want to dive into the arcpy source code, though... You can get the cim properties from the JSON, but setting them to the MappingLayerObject didn't work (but I also didn't try to make it work...) Your best bet is probably to use the name attribute to get the arcpy._mp.Layer from the active map like I did in line 43. Manipulating this object's cim does appear to work.
... View more
10-05-2023
12:44 PM
|
2
|
0
|
821
|
POST
|
Null geometries are created when you try to buffer too much. You probably have small polygons in your fc. In these cases, the buffer of one side would end up on the outside of the polygon on the other side, resulting in a null geometry. This is difficult to explain, so here is a quick sketch: On the left, a polygon (black) and a negative buffer (red) with appropriate buffer distance (blue). On the right, the buffer distance is too big for the polygon, so the buffer's sides would end up outside of the polygon, creating a nonsensical geometry (not saying that the buffer algorithm actually works this way, just as a concept). tl;dr: use an appropriately small buffer size or exclude polygons with small area from the calculation. To use your check, you have to put it before the actual error: var ImpCatchments = Featuresetbyname($datastore, "attains_au_catchments_Impaired")
var NegBuffer = Buffer($feature, -20, "meters")
if(NegBuffer == null) { return "Polygon too small" }
var IntImpCat = Intersects(NegBuffer,ImpCatchments)
var cnt = count(IntImpCat)
return IIF(cnt > 0, "Y", "N")
... View more
10-05-2023
12:16 PM
|
1
|
2
|
814
|
Title | Kudos | Posted |
---|---|---|
1 | 03-22-2022 11:52 PM | |
2 | 05-18-2023 12:45 AM | |
1 | 01-12-2023 06:22 AM | |
1 | 06-09-2022 10:42 PM | |
1 | 01-12-2022 04:43 AM |
Online Status |
Offline
|
Date Last Visited |
02-03-2024
06:14 PM
|