|
POST
|
Are you using your own network or an Esri provided one? If it's your own, are you sure that there are valid conections all the way along it?
... View more
04-15-2024
08:27 PM
|
0
|
2
|
1941
|
|
POST
|
Assuming you have access to the Network Analyst extension that Dan has linked, you setup your Start and Finish points with Route Names. You need a start point to go with each corresponding finish point. Think of it like this - if you have Point A and you want to calculate routes to Points M, N & O, you need 3 copies of Point A, each with a unique Route Name that is also referenced by each finish point (i.e. Route A-M, A-N & A-O). When you run the Solve tool to calculate routes, it recognises those route names and calcs the route from A to N, then another for A-M and again for A-O. The same dataset could also then contain start points B, C, etc and other finish points, and as long as you have those start points copied and named to match each required finish location, it will only calculate those routes. It seems like a simple concept, but it took me a while to figure this out so, thought I'd share it. Below is an extract from a python code that generates the Start and Finish points based on 2 input datasets (the start points actually being polygons so you can see the dissolve and conversion steps added in to deal with this). The code goes on to solve the network too, but I haven't added that as I haven't got it running properly in an automated manner (which is how it is supposed to run). I have a model that does this too for users to use in ArcGIS Pro (what I used to build the below code in the first place). # Variables - update these lines
SDPRoutes = "Output feature service" # ArcGIS Online feature service containing routes to be updated
origins = r"\\path\to\input\origin\features" # Input feature class or table (can be .csv/.xls/.xlsx/etc.) or service URL of feature service in ArcGIS Online
destinations = "\\path\to\input\destination\features" # Input feature class or table (can be .csv/.xls/.xlsx/etc.) or service URL of feature service in ArcGIS Online
nd_path = r"\\path\to\network\dataset"
travelmode = "RAV 3"
import arcpy, time, os
from arcgis.gis import GIS
from arcgis.features import FeatureLayer
# Start Timer
startTime = time.time()
# Overwrite Output
arcpy.env.overwriteOutput = True
try:
arcpy.CheckOutExtension("Network")
print ("Network Analyst license checked-out")
# Create GIS object
print("Connecting to AGOL")
#...login to ArcGIS Online section omitted...
# Create temporary FGDB
sdproutesgdb = arcpy.CreateFileGDB_management(arcpy.env.scratchFolder, "sdproutes")
print ("Temp FGDB created")
arcpy.env.workspace = arcpy.env.scratchFolder + "\\sdproutes.gdb"
print ("Workspace set to temp FGDB")
#...checks of routes in existing dataset omitted...
# Prep Origin data
origins_temp = arcpy.conversion.ExportFeatures(
in_features = origins,
out_features = arcpy.env.workspace + "\\Origins_Temp",
where_clause = "PatchClass = 1 AND Map_Symbol = 'Softwood'",
use_field_alias_as_name = "NOT_USE_ALIAS",
field_mapping = ,
sort_field = None
)
print("Origins exported")
origins_dissolved = arcpy.management.Dissolve(
in_features = origins_temp,
out_feature_class = arcpy.env.workspace + "\\Origins_Dissolved",
dissolve_field = "Ops_Code",
statistics_fields = None,
multi_part = "MULTI_PART",
unsplit_lines = "DISSOLVE_LINES",
concatenation_separator = ""
)
print("Origins dissolved by Ops_Code")
origin_points = arcpy.management.FeatureToPoint(
in_features = origins_dissolved,
out_feature_class = arcpy.env.workspace + "\\Origin_Points",
point_location = "CENTROID"
)
print("Dissolved origins converted to points")
origin_points = arcpy.management.AddFields(
in_table = origin_points,
field_description = "Name TEXT # 500 # #;RouteName TEXT # 1024 # #;Sequence LONG # # # #",
template = None
)
print("Route fields added to Origin points")
origin_points = arcpy.management.CalculateField(
in_table = origin_points,
field = "Name",
expression = "!Ops_Code!",
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print("Name field calculated")
origin_points = arcpy.management.CalculateField(
in_table = origin_points,
field = "Sequence",
expression = "1",
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print("Sequence field calculated")
static_origins = arcpy.analysis.Select(
in_features = origin_points,
out_feature_class = arcpy.env.workspace + "\\Static_Origins",
where_clause = ""
)
print("Static Origin points generated")
# Prep Destination data
fl = FeatureLayer(destinations)
fs = fl.query(where = "Delivery_Location_ID IN ('1015DA1', '1015DA2', '1043DA1', '1043DA6', '344D13', '410D10', '410DA1', '410DA2', '410DA8', '426DA1', '503DA1', '5097DA2', '5097DA7', '5102DA1')") # Query to only return required features
destinations_temp = fs.save(arcpy.env.workspace, "destinations_temp")
print("Required destinations exported from feature service")
destination_points = arcpy.analysis.Select(
in_features = destinations_temp,
out_feature_class = arcpy.env.workspace + "\\destination_points",
where_clause = ""
)
print("Destination Points generated with ObjectID's reset from 1")
destination_points = arcpy.management.AddFields(
in_table = destination_points,
field_description = "Name TEXT # 500 # #;RouteName TEXT # 1024 # #;Sequence LONG # # # #",
template = None
)
print("Route fields added to Destination points")
destination_points = arcpy.management.CalculateField(
in_table = destination_points,
field = "Name",
expression = "!Delivery_Location_ID!",
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print("Name field calculated")
destination_points = arcpy.management.CalculateField(
in_table = destination_points,
field = "Sequence",
expression = "2",
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print("Sequence field calculated")
_rows = static_destinations
)[0])
print("Static Destination count: " + str(DestinationCount))
TargetCount = OriginCount*DestinationCount
print ("Target Count = " + str(TargetCount))
# Iterate through Origins to replicate points for each Destination
print ("Start iterating Origin points to create 1 set of all Origin points for each Destination point")
while OriginCount < TargetCount:
print ("Origin count (" + str(OriginCount) + ") less than Target Count (" + str(TargetCount) + ") - Append data...")
arcpy.management.Append(
inputs = static_origins,
target = origin_points,
schema_type = "TEST",
field_mapping = None,
subtype = "",
expression = "",
match_fields = None,
update_geometry = "NOT_UPDATE_GEOMETRY"
)
OriginCount = int(arcpy.management.GetCount(
in_rows = origin_points
)[0])
print ("Origins Replicated")
sorted_origins = arcpy.management.Sort(
in_dataset = origin_points,
out_dataset = arcpy.env.workspace + "\\sorted_origins",
sort_field = "Name ASCENDING",
spatial_sort_method = "UR"
)
print ("Origins sorted by Name")
# Iterate through Destinations to replicate points for each Origin
print ("Start iterating Destination points to create 1 set of all Destination points for each Origin point")
while DestinationCount < TargetCount:
print ("Destination count (" + str(DestinationCount) + ") less than Target Count (" + str(TargetCount) + ") - Append data...")
arcpy.management.Append(
inputs = static_destinations,
target = destination_points,
schema_type = "NO_TEST",
field_mapping = r'Name "Name" true true false 500 Text 0 0,First,#,static_destinations,Name,0,500,destination_points,Name,0,500;RouteName "RouteName" true true false 1024 Text 0 0,First,#,static_destinations,RouteName,0,1024,destination_points,RouteName,0,1024;Sequence "Sequence" true true false 4 Long 0 0,First,#,static_destinations,Sequence,-1,-1,destination_points,Sequence,-1,-1',
subtype = "",
expression = "",
match_fields = None,
update_geometry = "NOT_UPDATE_GEOMETRY"
)
DestinationCount = int(arcpy.management.GetCount(
in_rows = destination_points
)[0])
print ("Destinations Replicated")
# Join Origins and Destinations to calculate route details
sorted_origins = arcpy.management.JoinField(
in_data = sorted_origins,
in_field = "OBJECTID",
join_table = destination_points,
join_field = "OBJECTID",
fields = "Name",
fm_option = "NOT_USE_FM",
field_mapping = None
)
print ("Destination names added to Origin points")
sorted_origins = arcpy.management.CalculateField(
in_table = sorted_origins,
field = "RouteName",
expression = '!Name!+"_"+!Name_1!',
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print ("Origin Route Names calculated")
arcpy.management.JoinField(
in_data = destination_points,
in_field = "OBJECTID",
join_table = sorted_origins,
join_field = "OBJECTID",
fields = "Name",
fm_option = "NOT_USE_FM",
field_mapping = None
)
print ("Origin names added to Destination points")
destination_points = arcpy.management.CalculateField(
in_table = destination_points,
field = "RouteName",
expression = '!Name_1!+"_"+!Name!',
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print ("Destination Route Names calculated")
merged_locations = arcpy.management.Merge(
inputs = [sorted_origins, destination_points],
output = arcpy.env.workspace + "\\MergedLocations",
field_mappings = 'Ops_Code "Ops_Code" true true false 8000 Text 0 0,First,#,sorted_origins,Ops_Code,0,8000;ORIG_FID "ORIG_FID" true true false 4 Long 0 0,First,#,sorted_origins,ORIG_FID,-1,-1;Name "Name" true true false 500 Text 0 0,First,#,sorted_origins,Name,0,500,destination_points,Name,0,500;RouteName "RouteName" true true false 1024 Text 0 0,First,#,sorted_origins,RouteName,0,1024,destination_points,RouteName,0,1024;Sequence "Sequence" true true false 4 Long 0 0,First,#,sorted_origins,Sequence,-1,-1,destination_points,Sequence,-1,-1;ORIG_FID_1 "ORIG_FID_1" true true false 4 Long 0 0,First,#,sorted_origins,ORIG_FID_1,-1,-1;Name_1 "Name" true true false 500 Text 0 0,First,#,sorted_origins,Name_1,0,500,destination_points,Name_1,0,500;Delivery_Location_ID "Delivery Location ID" true true false 255 Text 0 0,First,#,destination_points,Delivery_Location_ID,0,255',
add_source = "NO_SOURCE_INFO"
)
print ("Origins and Destinations merged into single dataset")
static_destinations = arcpy.analysis.Select(
in_features = destination_points,
out_feature_class = arcpy.env.workspace + "\\Static_Destinations",
where_clause = ""
)
print("Static Destination points generated")
# Get counts of input locations
OriginCount = int(arcpy.management.GetCount(
in_rows = static_origins
)[0])
print("Static Origin count: " + str(OriginCount))
DestinationCount = int(arcpy.management.GetCount(
in_rows = static_destinations
)[0])
print("Static Destination count: " + str(DestinationCount))
TargetCount = OriginCount*DestinationCount
print ("Target Count = " + str(TargetCount))
# Iterate through Origins to replicate points for each Destination
print ("Start iterating Origin points to create 1 set of all Origin points for each Destination point")
while OriginCount < TargetCount:
print ("Origin count (" + str(OriginCount) + ") less than Target Count (" + str(TargetCount) + ") - Append data...")
arcpy.management.Append(
inputs = static_origins,
target = origin_points,
schema_type = "TEST",
field_mapping = None,
subtype = "",
expression = "",
match_fields = None,
update_geometry = "NOT_UPDATE_GEOMETRY"
)
OriginCount = int(arcpy.management.GetCount(
in_rows = origin_points
)[0])
print ("Origins Replicated")
sorted_origins = arcpy.management.Sort(
in_dataset = origin_points,
out_dataset = arcpy.env.workspace + "\\sorted_origins",
sort_field = "Name ASCENDING",
spatial_sort_method = "UR"
)
print ("Origins sorted by Name")
# Iterate through Destinations to replicate points for each Origin
print ("Start iterating Destination points to create 1 set of all Destination points for each Origin point")
while DestinationCount < TargetCount:
print ("Destination count (" + str(DestinationCount) + ") less than Target Count (" + str(TargetCount) + ") - Append data...")
arcpy.management.Append(
inputs = static_destinations,
target = destination_points,
schema_type = "NO_TEST",
field_mapping = r'Name "Name" true true false 500 Text 0 0,First,#,static_destinations,Name,0,500,destination_points,Name,0,500;RouteName "RouteName" true true false 1024 Text 0 0,First,#,static_destinations,RouteName,0,1024,destination_points,RouteName,0,1024;Sequence "Sequence" true true false 4 Long 0 0,First,#,static_destinations,Sequence,-1,-1,destination_points,Sequence,-1,-1',
subtype = "",
expression = "",
match_fields = None,
update_geometry = "NOT_UPDATE_GEOMETRY"
)
DestinationCount = int(arcpy.management.GetCount(
in_rows = destination_points
)[0])
print ("Destinations Replicated")
# Join Origins and Destinations to calculate route details
sorted_origins = arcpy.management.JoinField(
in_data = sorted_origins,
in_field = "OBJECTID",
join_table = destination_points,
join_field = "OBJECTID",
fields = "Name",
fm_option = "NOT_USE_FM",
field_mapping = None
)
print ("Destination names added to Origin points")
sorted_origins = arcpy.management.CalculateField(
in_table = sorted_origins,
field = "RouteName",
expression = '!Name!+"_"+!Name_1!',
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print ("Origin Route Names calculated")
arcpy.management.JoinField(
in_data = destination_points,
in_field = "OBJECTID",
join_table = sorted_origins,
join_field = "OBJECTID",
fields = "Name",
fm_option = "NOT_USE_FM",
field_mapping = None
)
print ("Origin names added to Destination points")
destination_points = arcpy.management.CalculateField(
in_table = destination_points,
field = "RouteName",
expression = '!Name_1!+"_"+!Name!',
expression_type = "PYTHON3",
code_block = "",
field_type = "TEXT",
enforce_domains = "NO_ENFORCE_DOMAINS"
)
print ("Destination Route Names calculated")
merged_locations = arcpy.management.Merge(
inputs = [sorted_origins, destination_points],
output = arcpy.env.workspace + "\\MergedLocations",
field_mappings = 'Ops_Code "Ops_Code" true true false 8000 Text 0 0,First,#,sorted_origins,Ops_Code,0,8000;ORIG_FID "ORIG_FID" true true false 4 Long 0 0,First,#,sorted_origins,ORIG_FID,-1,-1;Name "Name" true true false 500 Text 0 0,First,#,sorted_origins,Name,0,500,destination_points,Name,0,500;RouteName "RouteName" true true false 1024 Text 0 0,First,#,sorted_origins,RouteName,0,1024,destination_points,RouteName,0,1024;Sequence "Sequence" true true false 4 Long 0 0,First,#,sorted_origins,Sequence,-1,-1,destination_points,Sequence,-1,-1;ORIG_FID_1 "ORIG_FID_1" true true false 4 Long 0 0,First,#,sorted_origins,ORIG_FID_1,-1,-1;Name_1 "Name" true true false 500 Text 0 0,First,#,sorted_origins,Name_1,0,500,destination_points,Name_1,0,500;Delivery_Location_ID "Delivery Location ID" true true false 255 Text 0 0,First,#,destination_points,Delivery_Location_ID,0,255',
add_source = "NO_SOURCE_INFO"
)
print ("Origins and Destinations merged into single dataset")
... View more
04-15-2024
06:56 PM
|
1
|
2
|
14938
|
|
IDEA
|
It would help for field users to also recognise when they are leaving their offline area (which means they can no longer capture/edit data). This has caught a few people out as they just see the basemap and think they can carry on as normal.
... View more
04-15-2024
05:32 PM
|
0
|
0
|
1116
|
|
DOC
|
Regarding the Drawing tools, our staff use the WaB version to place temporary labels on the map for quick prints. This isn't included in ExB yet. The first (February) document doesn't mention it in the Funcationality Description which was disheartening... ...but the other document (March) does list it as planned. The 2 documents seem to contradict each other though. Bit confusing.
... View more
04-14-2024
05:44 PM
|
0
|
0
|
43869
|
|
IDEA
|
@DanPatterson Thanks for the tip - I've made some edits to the post and title to better describe the request.
... View more
04-10-2024
05:10 PM
|
0
|
0
|
3642
|
|
IDEA
|
IDEA: Implement natural sorting in text fields throughout ArcGIS Pro (attribute tables, dynamic table elements, etc). USE CASE: When sorting numerical values in ArcGIS Pro, if these values are in a text field and are sorted in ascending order, it puts any number starting with a 1 (i.e. 101) before any number starting with a 2 (i.e. 20). I know I could add leading zero's to the numbers to get more accurate sorting, but I don't want to have to do this to then have to remove them in labelling (or to educate others to do this). It would be better if text sorting treated numbers holistically (or at least up to the point that a non-numeric character occurs). Note - in below dynamic table element examples, sorting is done on the Rate column first then the Block column. I know it's better to store numbers in integer type fields, but in the above use case, blocks could be labelled with alpha delineators as well: 1A, 1B, 5, 2, 9, 3, 4A, 4B, 6, 7, 8, 10, 11A, 11B ...and I would want these to sort to match the numbers first then the letters (logically) and not end up with 9 after 11A and 11B: 1A, 1B, 2, 3, 4A, 4B, 5, 6, 7, 8, 9, 10, 11A, 11B. Currently these values would sort like this: 10, 11A, 11B, 1A, 1B, 2, 3, 4A, 4B, 5, 6, 7, 8, 9
... View more
04-09-2024
07:19 PM
|
20
|
3
|
3781
|
|
IDEA
|
@AndreaGalligari maybe what is discussed here could help? How to override values for fields with calculated expressions in Forms and the Editor widget (esri.com)
... View more
04-09-2024
05:17 PM
|
0
|
0
|
2021
|
|
IDEA
|
Yes please! Webhooks are still a bit of a mystery to me. One day I'll dive in proper and figure it out as I'm sure we are missing out on opportunities to improve our workflows,m especially regarding feature creation/update/deletion notifications.
... View more
04-09-2024
05:07 PM
|
0
|
0
|
1832
|
|
BLOG
|
I assume it's got something to do with calculating a field if it's empty, but then it's not empty so kid of a circular logic problem. Are there any other fields that get completed when the observation date is done that you could reference instead? Like an Observers Name? Or if the EditDate matches/doesn't match the CreationDate?
... View more
04-07-2024
05:09 PM
|
0
|
0
|
11392
|
|
IDEA
|
I was looking to use a URL in the popup of our plantation layer to launch Survey123 and pass the geometry across, but what I REALLY wanted was to use Arcade to not only pass the geometry of the selected polygon, but to also select all polygons with common attributes, dissolve those and pass across a multipart polygon. Doesn't seem I could make this happen. IDEA: Add a Dissolve function for aggregating data. I can see other uses for this type of function as well (i.e. reporting/summarising in popups but understand this can be achieved in other ways as well).
... View more
04-04-2024
10:00 PM
|
6
|
2
|
1616
|
|
IDEA
|
Looking at Data Pipelines and how it could be used to manipulate data and automate new workflows instead of developing Model Builder tools in ArcGIS Pro, but we found we were limited with few geometry modifying tools. IDEA: Add the "Dissolve" tool to Data Pipelines so that features can be buffered and potentially used in other existing (or new) tools. Our use case was to take a layer with lots of polygons (plantations) and wanted to dissolve to get larger compartment multi-part polygons that could then trigger (via popup URL) and be passed as geometry to a Survey123 form on an annual schedule for regular inspections.
... View more
04-04-2024
09:43 PM
|
0
|
2
|
1394
|
|
IDEA
|
Hi @BethanyScott It's not publicly shareable data , though I can share to a test group and add you - I just need your argis online username. I tried bethanyscott but it said that account had insufficient privileges? I've just done a quick test in Pro using Model Builder then adding the output to a map. The below screenshots show the results of doing a Spatial Join... ...using "Contains": ...using Intersect: Both the above worked well, but only included the intersecting features in the output dataset. So I've run it again with "Add Spatial Join" to create a temporary join with all Target features retained. This yielded a similar results as Pipelines (though some areas were left of and others were returned instead).
... View more
04-04-2024
05:38 PM
|
0
|
0
|
1490
|
|
IDEA
|
@SarahSaint-Ruth worth mentioning whether this functionality is only in Field Maps Designer and not yet in the WebMap smart form editor as well. Thats a lesson I learnt recently on another scenario regarding new fields, default values and feature templates. You don't see that stuff in the WebMap smart form editor - only Field Maps Designer.
... View more
04-04-2024
05:07 PM
|
0
|
0
|
2082
|
|
IDEA
|
I'm attempting to do a spatial join and unfortunately the 2 input datasets have different spatial references. This means that the 2nd is transformed to match the first. The data should align, but the transformation means there are slight differences. These differences are resulting in features joining that should not when using the "intersects" or "contains" options. In ArcGIS Pro, i frequently add a negative search distance to reduce the chance of overlaps around the edges, but this is not possible (yet) in Data Pipelines. I even tried the "Near geodesic" option with a negative distance (5 metres) but that results in an error when run/previewed. In the screenshot below, you can see the incorrectly join areas circled. The blue hatch indicates what should have been joined - the solid yellow areas have only joined based on the slightest overlap/touch at the boundaries. I even tried to include a projection step prior to the spatial join to remove the slight shift, but it made no discernable difference.
... View more
04-04-2024
12:28 AM
|
0
|
3
|
1587
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | yesterday | |
| 2 | yesterday | |
| 2 | 2 weeks ago | |
| 2 | 2 weeks ago | |
| 4 | 2 weeks ago |
| Online Status |
Offline
|
| Date Last Visited |
yesterday
|