|
IDEA
|
Could you not create Lat & Long fields and use Arcade to calculate the values? (fields would not be manually editable)
... View more
05-01-2024
06:37 PM
|
0
|
0
|
3508
|
|
POST
|
Awesome. Thanks for the extra info. This will help when explaining to management how it all works.
... View more
04-30-2024
05:19 PM
|
0
|
0
|
4716
|
|
POST
|
Yep, I feel more coordination will be needed in the future. I've just done a test run creating an offline capable webmap, uploaded a new vtpk and referenced that in the advanced offline settings. I then downloaded the vtpk with the 1st offline area and made some edits. I've then uploaded a 2nd vtpk and done the Replace layer function on the hosted tile layer and deleted the old vtpk and the archived tile layer. The existing offline area continued to function before and after updating the advanced offline settings to reference the new vtpk and with a second offline area downloaded using the new vtpk (once it had downloaded). I assume this means that the original vtpk is kept on the mobile device even after being replaced in the webmap? And would it continue to stay on the device after any offline areas referencing it have been removed? If this is the case, I can see it chewing up your devices storage over time with basemaps accumulating.
... View more
04-29-2024
08:00 PM
|
0
|
0
|
4734
|
|
IDEA
|
@cbp-geus yep - all very good points. To make it work offline you would need to create 2 different hosted views of the layer, not just duplicate the layer in the map. Scale intervals can certainly be beneficial to reduce that clutter as you zoom out.
... View more
04-29-2024
07:56 PM
|
0
|
0
|
4056
|
|
POST
|
Thanks again @KerriRasmussen for the pointer. I believe this will work nicely for us as a solution. I'm testing it right now. The only part I'm not sure of is what will happen when we run the Vector Tile Package hosted layer update process. As per the screenshot below, we would end up deleting the old Vector Tile Package and the new hosted tile layer after doing the replacement. This would obviously break the link in the Advanced Offline settings to the old vtpk. Do you know what this will do to maps with that file set for offline use?
... View more
04-28-2024
08:47 PM
|
0
|
2
|
4764
|
|
IDEA
|
Not ideal, but a workaround that may work depending on your situation is a duplicate of the layer - one with labels on and the other off. You can then turn them on and off as required in the map layers list.
... View more
04-28-2024
05:55 PM
|
0
|
0
|
4089
|
|
POST
|
Hi @KathleenCSki. Most of our devices are Samsung mobile phones (various models but many from the A series) with a scattering of Samsung tablets. I believe our IT section use Microsofts InTune MDM platform. It contains limited control over some Field Maps settings, but basemaps are not one of them. @KerriRasmussen I think you've just given me my answer. Doing a test run now. We have 2 versions of a basemap that cover all of Western Australia. One is 566MB and the other 1.2GB. So pretty chunky, but like you say, a once off download shouldn't be too much to handle for most users with a bit of forward planning and comms. We update these annually, so that will be my next line of research - how will these handle the upload and replace process we do.
... View more
04-28-2024
05:24 PM
|
0
|
0
|
4773
|
|
POST
|
Our organisation has recently started implementing Mobile Device Management using InTune on new devices as they are rolled out. This has cause us to hit a bit of a snag. Up to now, we have recommended that users take a Vector Tile Package that is generated by our GIS Team covering the state and sideload it to their device to streamline offline area downloads. This file is then referenced in the webmap settings to be used for offline areas. We don't use Mobile Map Packages or specify offline areas in Field Maps Designer, as our staff are too irregularly dispersed to manage it that way. Staff instead determine what areas they need offline when they need them. This has worked fine until now, where the MDM devices prohibit the user from sideloading our .vtpk onto their device (via USB connection to their PC). No file explorer option is available to them. Does anyone else have experience with this and possible solutions we can look at?
... View more
04-24-2024
12:43 AM
|
1
|
12
|
5329
|
|
BLOG
|
Hey @JesseCloutier , it looks like a part of the 2nd paragraph under the Staying True To “We Care for You” heading is incomplete.
... View more
04-23-2024
05:37 PM
|
3
|
0
|
3257
|
|
IDEA
|
When using Model Builder and generating data that is then output to a map using the Collect Values tool with the output set as a parameter, we can currently use the Import Symbology tool to import layer styling from a Layer File saved in an accessible location (i.e. on your machine or network). Whilst this is useful, most of the time I wish I could hard code the layer file into the model so that it's not reliant on a file sitting in a folder somewhere to style the outputs. If I could style a layer in a map with symbology, labels, etc then save a Layer File, instead of referencing that layer file in the model as an input, I would like to be able to Drag and Drop it as a standalone item with all it's information saved directly in the model. This would reduce the chance of the layer file being moved, deleted or modified unintentionally and thereforce impacting the output of the model.
... View more
04-22-2024
09:26 PM
|
2
|
0
|
912
|
|
POST
|
So not too long ago I learnt that the GetUser(fullName) expression always requires an internet connection to work. If used in an Offline map, it still pulls from the web (or tries to). If the device is in Flight Mode, it would fail. We implemented a work around for this to use GetUser(username) which does work offline. What I want to know is, are there other expressions that pull on the internet even when in an offline map? I would like to know so I can avoid using them if possible. I believe these to be causing issues with features returning calculated attributes when there isn't sufficient signal.
... View more
04-18-2024
08:24 PM
|
3
|
0
|
1180
|
|
POST
|
Yep - it's just the Network Analyst extension as you've shown. I do most of my python work using IDLE or within Pro itself. I've never used Jupyter Notebooks or Visual Studio Code.
... View more
04-16-2024
05:13 PM
|
1
|
0
|
14866
|
|
POST
|
I haven't used the Nearest Facility funciton so not sure if this is part of it, but there may be a search distance parameter that limits how far a point can be from a road before it is excluded. If it's beyond the set distance, no route is returned.
... View more
04-15-2024
09:35 PM
|
0
|
0
|
1915
|
|
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
|
1928
|
|
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
|
14925
|
| Title | Kudos | Posted |
|---|---|---|
| 2 | 2 weeks ago | |
| 2 | 2 weeks ago | |
| 4 | 2 weeks ago | |
| 1 | 2 weeks ago | |
| 2 | 3 weeks ago |
| Online Status |
Online
|
| Date Last Visited |
yesterday
|