|
POST
|
The else is redundant, easier to read without the indent //Script title: Set polyline M-values to cumulative length of line
var geom = Dictionary(Text(Geometry($feature)));
var paths = geom['paths'];
//Using the Equals() function doesn't work as expected. See: Arcade: Editing M-values not treated as change to geometry (https://community.esri.com/t5/arcgis-pro-questions/arcade-editing-m-values-not-treated-as-change-to/m-p/1153917)
//if (Equals(Geometry($feature), Geometry($originalfeature)) ) {
if (Text(Geometry($feature)) == Text(Geometry($originalfeature))) {
console("The geometry has not changed. We don't need to redefine the M-Values.")
return
}
//Alternatively, this could be done with the Arcade distance() function. I chose to do the math manually so that the script can be used elsewhere, such as VSCode (for debugging).
function pythagoras(x1, y1, x2, y2) {
return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));
}
var oldX = paths[0][0][0];
var oldY = paths[0][0][1];
var line_length = 0;
for (var path_idx in paths) {
for (var point_idx in paths[path_idx]) {
var newX = paths[path_idx][point_idx][0];
var newY = paths[path_idx][point_idx][1];
//For multi-part features, we want the M-value for additional parts to start at the last M-value from the last part. We don't want to measure the distance *between* parts.
//So, for the first vertex in a given part, we will skip calculating the length between vertices.
if (point_idx != 0) {
line_length += pythagoras(oldX, oldY, newX, newY);
}
//We can use a negative slice: it will work when there is no Z.
paths[path_idx][point_idx][-1] = line_length;
oldX = newX;
oldY = newY;
}
}
console("The geometry has changed. So we *will* redefine the M-Values.")
return { "result": { "geometry": Polyline(geom) } };
... View more
03-21-2022
12:50 PM
|
1
|
0
|
5942
|
|
POST
|
You will need to use a preset template - Place the Meter and Flow valve and create the association - Select the features - Click Move on the Editor Toolbar, a yellow circle will appear in the middle of the two features - Hold Control Key and hover the yellow circle, click and drag this to the flow valve - Open Manage Templates - Go to Flow Valve and generate a new preset template This will use the flow valve as the insert point and the snapping. You can use the point and rotate tool to place the feature and rotate it. I would like to see group templates support Junction to Junction associations, so please log the enhancement.
... View more
03-15-2022
12:37 AM
|
0
|
1
|
2546
|
|
POST
|
The b_rules is in the Asset Package geodatabase. You need to open that database in a catalog pane/view. You need to fix that table.
... View more
03-14-2022
05:40 AM
|
0
|
0
|
3277
|
|
POST
|
Looks pretty good, minor tweaks and comments //Only do the calculation if the geometry was changed/edited. // I like to exit early when condition is not met, makes the code a little more readable if (Equals(Geometry($feature), Geometry($originalfeature))) { return } var geom = Dictionary(Text(Geometry($feature))); var paths = geom['paths']; //Alternatively, this could be done with the Arcade distance() function. I chose to do the math manually so that the script can be used elsewhere, such as VSCode (for debugging). function pythagoras(x1, y1, x2, y2) { return sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2)); } // Easier to read when on multi lines and moved out of the loop, it was being reset on each part, not sure that is what you wanted var oldX = paths[0][0][0]; var oldY = paths[0][0][1]; // dont use length, that is a reserved function name var line_length = 0; for (var path_idx in paths) { for (var point_idx in paths[path_idx]) { var newX = paths[path_idx][point_idx][0]; var newY = paths[path_idx][point_idx][1]; line_length += pythagoras(oldX, oldY, newX, newY); // can use a negative slice, will work when there is no Z paths[path_idx][point_idx][-1] = line_length; oldX = newX; oldY = newY; } } console(paths); return { "result": { "geometry": Polyline(geom) } }; //Output: [[[0,5,0],[10,10,11.180339887498949],[30,0,33.54101966249685],[50,10,55.90169943749475],[60,10,65.90169943749476]]] } //Generic JS version: https://jsfiddle.net/5m1c69g3/
... View more
03-13-2022
05:15 AM
|
1
|
2
|
6029
|
|
POST
|
We have the CP modeled in a separate tier group, so the two commodities can be modeled separately. We use a network attributes and categories to ensure gas does not flow on a electric line.
... View more
03-11-2022
07:04 AM
|
1
|
0
|
2154
|
|
POST
|
The data is fine, the issue are the utility network rules, you need to define the rules down to the terminal. Open the B_rules table, fine those rows and set the appropriate terminal name or *
... View more
03-11-2022
05:52 AM
|
0
|
0
|
3367
|
|
POST
|
We model the CP network as a subnetwork in the Gas Domain. As we need the metal gas pipes be part of the CP network. If you model it separately, you will have to duplicate these features to build out a CP subnetwork.
... View more
03-11-2022
03:35 AM
|
0
|
0
|
2159
|
|
POST
|
Those devices have a terminal configuration, so you either need to specify the appropriate terminal for those records or use * so the rule is created on all terminals.
... View more
03-11-2022
03:24 AM
|
0
|
0
|
3517
|
|
BLOG
|
In this article, I wanted to discuss a different approach of extracting data to power reports for branched versioned datasets, like the Utility Network. We could leverage geoprocessing tools to query the data for the reports, but many of these tools pull down the records to the client and then preform the statistic. It is more efficient and faster to ask the database to do this work, so the statistics are preformed. To do this, we can use the OutStatistics parameter on the Query Rest Endpoint. If you are not familiar with this parameter, scroll down to outStatistics on the Rest API Query doc. You can test using this capability, but browsing to the rest page one of your features services, selecting a layer and opening the query page. Since you will want to run these queries regularly to feed reports, we developed the FeatureServiceStat python script that leverages the ArcGIS Python API to make the query and store the results as csv files. To set up this script, fill out the credentials to access the service, the item ID from the portal to the feature service, the output folder and a lookup json file to convert subtype and domain codes to descriptions(more on this later). MikeMillerGIS_0-1646912055319.png Next, review the sum_stats dictionary. The keys are the class names to query. In the example below, the Feature Service has a layer named ElectricDevice. Next, fill out the queries you want to preform. You can specify 1:N queries. Details of each query definition name: The name of the resulting csv file where: This value is mapped to the where parameter grouped_by: These values are mapped to the groupByFieldsForStatistics parameter stats_info: These values are mapped to the outStatistics parameter bits(Optional): For electric, phase information is stored as a bitwise domain. If you want break the results by bit, such as the KVA on phase A, Phase B and Phase C, fill this dictionary out with the key representing the bit value and the description of bit description bit_field(Optional): The field with the bit values. Only required when bit is specified. This field must be in the group_by parameter. config.png This script produces as CSV for each stat defined and will look like this: MikeMillerGIS_0-1646911957324.png Looking at the XfrCount csv, you can see the count of transformers and the Total KVA per subnetwork and phase, as well as those values split out by the individual phase since we specified the bit information. MikeMillerGIS_1-1646911983433.png Now back to that code_lookup parameter. Since we use subtypes and coded value domains, the code is returned in the query. To make the results easier to interrupt, the script uses a code lookup json file to convert the codes to descriptions. To generate this file, use the build_lookup,py file and specify the path to the utility network and output file. MikeMillerGIS_2-1646911983435.png This generates a file, like below for your data, that the FeatureServiceStats.py uses. MikeMillerGIS_3-1646911999396.png Looking back at our XfrCount csv, you can see columns with the original phase and asset group values, but since we used the lookup file, new columns with their description have been added on the right. MikeMillerGIS_1-1646911983433.png This script is just an example to highlight these capabilities. We hope it gives you some ideas on how to utilize the outStatistics parameter in your organization or use this parameter in the workflows you are building. Thanks Mike ** Edit 1-12-2023 I updated the FeatureServiceStats.py module to load the hidden system layers.
... View more
03-10-2022
02:37 PM
|
4
|
11
|
5002
|
|
POST
|
I believe if you use FeatureSetByName with $datastore and ensure you check Exclude from Client Evaluation, the rule will search the database for the FC. You may not be able to use the FeatureSetByRelationshipName. So you will just have to built the query using PKey/FKey values. Something like this: https://github.com/Esri/arcade-expressions/blob/master/attribute_rule_calculation/MoveFieldToParent.js
... View more
03-06-2022
06:33 AM
|
1
|
1
|
1728
|
|
POST
|
Strongly advise against call Geometry in a loop, declare a variable outside and set that to the geometry. Edit: I fixed this example so it does not call geo in a loop - Source: ESRI’s GitHub of Arcade expressions - CreatePointsAlongLine var geo = Geometry($feature); for (var part in geo.paths) { var line_part = geo.paths[part] Geometry are immutable, so you cannot change the X,Y,Z,M of one, but a trick is to convert the geometry to text and then to a dict, then you can edit the shape and return it to update the feature. If you are not modify the geometry, then you do not need to do it. var current_line_geo = Geometry($feature);
var line_geo = Dictionary(Text(current_line_geo));
var paths = line_geo['paths'];
for (var path_idx in paths){
for (var vert_idx in paths[path_idx]){ To understand paths versus just a list of vertices(or is it vertex's), lines can be multipart, each part is a path, each path is composed of 2 or more vertices. Hope that helps
... View more
03-06-2022
06:24 AM
|
6
|
0
|
4994
|
|
POST
|
Are you creating Junction-Edge associations between a point and a line? There is a bug in File GDB that allows this and J-E between two spatial features is not supported.
... View more
03-05-2022
05:25 AM
|
0
|
2
|
2033
|
|
POST
|
I use pycharm, as I do mostly python development. I typically save my arcade as .js files. For the most part it works pretty good. @PaulLeBlanc1 put together this syntax for arcade in n++ a while back. Probably needs to be updated for some of the new methods.
... View more
03-01-2022
02:28 AM
|
2
|
0
|
6612
|
|
BLOG
|
@VanessaSimps that is very hard to answer as it depends on the model. Asset Groups and Asset Types that are used as subnetwork controllers are required if you want to build subnetworks. Fields used in Network Attributes may be needed depending on the subnetwork definition(for instance Status with open and closed).
... View more
02-24-2022
10:11 AM
|
0
|
0
|
5757
|
|
POST
|
Have you thought about converting the source data to use GlobalIDs as the relationship key? https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/migrate-relationship-class-tool.htm Then on append, if you set the field type to Guid instead of Global ID, it should let you preserve the global ID on import, so the source and target have the same global id. We are looking at how to streamline this process with the Data Loading Tools.
... View more
02-23-2022
02:25 AM
|
1
|
1
|
2689
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 2 weeks ago | |
| 1 | 2 weeks ago | |
| 1 | 2 weeks ago | |
| 2 | 07-07-2026 06:45 AM | |
| 1 | 06-26-2026 09:15 AM |
| Online Status |
Offline
|
| Date Last Visited |
2 weeks ago
|