Rounding double fields error in ArcMap

I have received an odd error message recently when trying to set up a label expression in ArcMap using Python parser.

I have a field of Double type and I want to show its value rounded in a label. Shouldn’t be more difficult than

int([AREA])

But I am getting an error message:

The expression contains an error.
Modify the expression and try again.

Error 0 on line 0.
Error running expression: esri__FindLabel(ESRIExpressionArg0)
Traceback (most recent call last):
File “<expression>”, line 1, in <module>
File “<string>”, line 2, in esri__FindLabel
ValueError: invalid literal for int() with base 10: ‘6380,614’

This is interesting. As it turns out, the double field’s string representation is used during the evaluation. On a virtual machine I’ve used, the locale that I’ve used had a comma , as the decimal symbol. So, in order to make it work I have to use the str.replace method:

int(float([AREA].replace(',', '.')))

Alternatively, if you want/can change the locale settings in Windows to use a dot . instead of a comma ,, then you will not need to run the replace method. It would be sufficient to run int(float([AREA]))

Small thing but hope this will save some time for other peer users!

Advertisements

Using SQL Server constraints and geodatabase domains

Attribute constraints

Many ArcGIS users use geodatabase domains to allow data editors to enter for certain attributes only certain values, either within a range or from a set of coded values. This functionality streamlines data editing and is very helpful indeed. However, having a geodatabase domain set for a field doesn’t actually prevent users from typing in value that is either outside of range or not in the list of coded values.

Entrance of illegal values can be done either programmatically using arcpy or SQL or by editing the attribute table of a feature class using Field Calculator. To be able to find out which features have illegal attribute values, you would need to select all of your features in the editing session and click Editor > Validate Features. This will select features with illegal values.

But what if you would like to let your users pick only certain values when editing the features and prohibit entering any illegal values? To do this, you could use database constraints such as foreign key constraint. In fact, I have already answered this exact question on GIS.SE: Restrict values to domain codes (beyond the attribute table).

In the end of the post, please look at the code snippet of what should be done in SQL. 

Now you can just use GP tool Table To Domain which will let you create a geodatabase domain from the dbo.CityType table as well as add the coded values into it. Then you can assign this domain to a field Type in the Cities feature class using the GP tool Assign Domain To Field.

Now user will get an error window in ArcMap (returned from SQL Server) every time they will try to enter illegal values into the field and save the feature. One thing to keep in mind when embracing this workflow is that you’d need to go to Editor toolbar > Options > Attributes tab and enable the option Display the attributes dialog before storing new features. This is necessary to do if you don’t specify any default value for this field that is stored within the dbo.CityType table. In this case, newly created features will have no value associated with the Type attribute and you won’t be able to digitize a feature on the map without getting the error message.

Spatial constraints

Another thing that may bug you is the geodatabase topology. It’s very handy when you have inherited a large suite of feature classes and you would like to enforce some integrity rules concerning the spatial relationships between features in those feature classes. However, if your data is stored in a multi-user geodatabase, then you could create own rules that would prohibit users from creating features that break those rules. Using ArcGIS geodatabase topology it is still possible to create a feature that would be considered invalid in terms of its relationship with another feature (say school point inside a lake polygon), however the only way to find this out is to validate topology on existing features.

Using SQL Server triggers, it is possible to specify the spatial rules and prevent creation of features that don’t follow these rules. Below is a simple example of a trigger that won’t let ArcMap users to digitize a point on the map to create a point feature that is located outside of the boundaries of the California state.

Network analysis with Esri routing services using Python

Good news for everyone who loves Python and routing! Now you can submit the routing requests using your input stops with the help of Esri Directions and Routing Services available to all organizations with the ArcGIS Online subscription and the ArcGIS Python API.

Maybe you use the ArcGIS API for JavaScript based web application or a Web App Builder application with the Directions widget or the ArcGIS Online Map Viewer. Some other users have built own Python (or other language based) scripts accessing the Esri routing services via the ArcGIS REST API in an own script or an application. I have been doing this using the ArcREST Python package.

Now you can use the ArcGIS API for Python to submit synchronous or asynchronous calls to the various routing services. Please refer to this ArcGIS REST API Help page to learn more what solvers are supported and how each of them works.

With the new Python API, working with the routing services became really easy. Many sample notebooks showcasing the routing services just got published to the ArcGIS API for Python documentation page.

Keep in mind that some of the routing related tools are also available as a part of Spatial Analysis Services. The notebook for these tools is available here.

Synchronous solvers:

Asynchronous solvers:

Network Analyst and ArcPy: finding k-alternate path

Using ArcGIS Network Analyst extension, it is possible to find out the best route between a pair of points (best is defined in terms of the impedance — it can the shortest or the fastest route, for instance). However, you might like having multiple alternatives to the best route which one usually refers to as the K shortest paths.

The K shortest path routing algorithm is

an extension algorithm of the shortest path routing algorithm in a given network.

When solving a route between a pair of points, Network Analyst finds only a single route that is considered to be the best. That is, one cannot get a number of routes while solving a Route layer. However, this is something many of you have seen when routing using Google Maps or HERE, for instance.

I got curious and have started searching for this algorithm implementation using ArcGIS Network Analyst. I’ve found a very useful Esri forums post by a former Esri Network Analyst product engineer Michael Rice who wrote that

At the ArcGIS 10 release, you can approximate a k-shortest paths solver using the enhanced barrier features. Additionally, for line and polygon barriers, instead of just restricting the parts of the network that are covered by their geometry, you can opt to simply scale the costs of the parts of the network covered by the geometry.

Therefore, to approximate k-shortest paths, you can do the following:

1. Solve the route to get the best path
2. Take the current best path and load it as a polyline barrier with a scale factor of x
3. Repeat

Note that by scaling the polyline barrier instead of restricting it, this will allow
the next path to reuse some of the same edges along the previous path if necessary, but at a higher cost than in previous paths. Also note that when multiple line barriers apply to the same edge, the final scale factor for the cost of that edge becomes the product of their individual scale factors. For example, if there are two line barriers applied to some edge with scale factors x and y, respectively, the scaled cost of traversing that edge will be x*y*originalEdgeCost.

This means that the more an edge is reused across different paths, the less likely it will be to be used in any subsequent paths as the process discussed above continues to iterate.

This approach will technically not guarantee a true k-shortest path solve, so we must
be careful not to incorrectly label it as such. As I said previously, it is merely an
approximation for this concept. A more appropriate name might be to call this a
k-alternate path approach (as opposed to shortest). The alternate paths you get will
ultimately depend on the scale factors you use.

I’ve written a Python add-in that given a number of alternative routes to find, will generate a new feature layer with a number of routes solved. I have used the workflow Michael described loading a solved route as a polyline barrier for all subsequent solve operations. You can use this code when you want to generate multiple alternate routes. This is how it looks in ArcMap.

2017-04-27 15_12_00-Routing.mxd - ArcMap

The Python code to be used to make the add-in:

Call ArcGIS Pro .NET SDK class library from Python

As some of you may already know, it is possible to interact with ArcObjects COM libraries using Python with the help of comtypes module. This means a whole lot for any GIS analyst who at some point may hit the limitations of arcpy package and will need to do something using ArcObjects which provide a fine-grained API into the ArcGIS components.

If you switch to ArcGIS Pro, though, you won’t be able to run your old ArcObjects code that, for instance, will hide or show map grids (graticules) in map layout before exporting the map (this is not supported with arcpy). Even though ArcGIS Pro is shipped with arcpy, its functionality is not any richer than of ArcGIS Desktop based arcpy (at least for now).

However, because ArcGIS Pro comes with .NET SDK, it becomes relevant to learn how to access .NET .dll files and access the methods of classes available within the class libraries. I’ve tested to use pythonnet module and it worked great to access a class library authored with Visual Studio 2015 and Visual C#.

In order to make calls to .dll files compiled based on .NET code (in my case, it’s C#) using Python, you would need to install a Python package called pythonnet. Learn more at Calling a C# library from python.

However, accessing the ArcGIS Pro .NET libraries isn’t that easy as there are many dependent references involved. There is support for embedding the core functionality of ArcGIS Pro (such as accessing the geodatabase data, iterating features with cursors, constructing geometries etc.), however, one is supposed to access this functionality either using a console application or a WPF application.

There is a Python module called subprocess that would let you get the result of console app execution as a string which you could load into a Python data structure to use later, however, this is not a very elegant way to proceed. You basically author your console apps and then use Python to call those apps supplying the input arguments. This is probably the easiest way to get your .NET code executed from Python, though, as you have everything you need already installed.

An alternative approach is to compile a class library using x64 platform in Visual Studio and then access it from 64 bit Python (your ArcGIS Desktop x86 Python won’t work). Read more about accessing the core of .NET SDK at ProConcepts CoreHost.

Here are the steps involved. Please mind that this can get messy with all those Python modules installations, so you might like spinning a virtual machine or at least a virtualenv for this.

  1. Build your class library in Visual Studio for x64 platform.
  2. Install pythonnet for x64.
  3. Install pywin32 for x64.
  4. Copy two .dll files from:
    ​C:\Python27\ArcGISx6410.4\Lib\site-packages\pywin32_system32 to C:\Python27\ArcGISx6410.4\Lib\site-packages\win32\lib
  5. You should be able to run the code in the snippet below.

 

ArcGIS Pro vs ArcGIS Desktop: geoprocessing tools

Both ArcGIS Desktop and ArcGIS Pro have a suite of toolboxes with hundreds of geoprocessing tools available. However, there are still quite a few tools that are available only in ArcMap and have not been ported to Pro. You can find the list of those tools at the Help page Tools that are not available in ArcGIS Pro.

However, what not so many people may know is that there are actually quite a few tools that are available exclusively in ArcGIS Pro. They have never existed in ArcMap in other words. They may or may not become a core part of the ArcGIS Desktop ArcToolbox. I have seen that many of the tools added to ArcGIS Pro 1.3 have been added to ArcGIS Desktop 10.5. A good part of them is specific to Pro, however, and would not make sense in ArcMap, such as Consolidate Project or Package Project tools. However, there are some tools that are applicable to both environments as they operate on geodatabase, for instance, Alter Domain, or with a network dataset, for instance, Create Network Dataset From Template.

To be able to find out what tools are available in ArcGIS Pro and not available in ArcGIS Desktop, I’ve written a tiny Python script that reads all the toolboxes available in the both installations and then compares them. You would need to run the code for Pro and Desktop Python installations, of course.

As I need to call Python installed in Pro and Desktop, I prefer to use a .bat file for this:

"C:\Python27\ArcGIS10.4\python.exe" "C:\GIS\Temp\ToolLister.py" "Desktop"
"C:\Program Files\ArcGIS\Pro\bin\Python\Scripts\propy.bat" "C:\GIS\Temp\ToolLister.py" "Pro"

After calling this .bat file, you will get two .json files each containing the tools available in these two environments.

Please note that I have run this code for ArcGIS Desktop 10.4 and ArcGIS Pro 1.4.

The code for your reference (ToolLister.py):

The list of tools present in Pro that are not in Desktop

ArcGIS Pro does have some new toolsets we never had in Desktop.

Standard Feature Analysis

The Standard Feature Analysis toolbox contains tools for performing spatial analysis on feature data in your portal.

Raster Analysis

The Raster Analysis toolbox contains a set of powerful tools for performing raster analysis on data in your portal. By distributing the processing between multiple server nodes, you can efficiently process large datasets in less time than ever before.

GeoAnalytics Tools

The GeoAnalytics Tools toolbox contains a set of powerful tools for performing spatial analysis on big data. GeoAnalytics Tools are powered by your ArcGIS GeoAnalytics Server. ArcGIS GeoAnalytics Server distributes the analysis between multiple server nodes. By using distributed processing, you can process large datasets in less time.

And here are the new tools in existing toolboxes:

Geostatistical Analyst Tools
  • EBKRegressionPrediction_ga
  • GALayerToRasters_ga
Editing Tools
  • AlignFeatures_edit (since Desktop 10.5 only)
  • CalculateTransformationErrors_edit (since Desktop 10.5 only)
Analysis Tools
  • EnrichLayer_analysis
  • PairwiseIntersect_analysis
  • SummarizeWithin_analysis
  • PairwiseDissolve_analysis
  • SummarizeNearby_analysis
  • PairwiseBuffer_analysis
  • SplitByAttributes_analysis
  • GraphicBuffer_analysis
Spatial Analyst Tools
  • LocateRegions_sa (since Desktop 10.5 only)
  • RemoveRasterSegmentTilingArtifacts_sa (since Desktop 10.5 only)
3D Analyst Tools
  • ClassifyLasBuilding_3d (since Desktop 10.5 only)
  • TileLas_3d (since Desktop 10.5 only)
Conversion Tools
  • AddRasterToGeoPackage_conversion (since Desktop 10.5 only)
Data Management Tools (some of the tools may be available since Desktop 10.5)
  • AlterDomain_management
  • AddRelate_management
  • RemoveRelate_management
  • CreateMobileMapPackage_management
  • CreateVectorTileIndex_management
  • CreateVectorTilePackage_management
  • MosaicDatasetToMobileMosaicDataset_management
  • CreateSceneLayerPackage_management
  • EnableCOGO_management
  • DisableCOGO_management
  • BuildStereoModel_management
  • InterpolateFromPointCloud_management
  • ComputeCameraModel_management
  • GeneratePointCloud_management
  • ComputeMosaicCandidates_management
Space Time Pattern Mining Tools
  • LocalOutlierAnalysis_stpm
Network Analyst Tools
  • CreateNetworkDatasetFromTemplate_na
  • CreateTemplateFromNetworkDataset_na

Hope you will find this list useful. If your main workflows are still ArcGIS Desktop based (which I believe they are for most of us), keep in mind that you can call ArcGIS Pro Python 3.5 installation to take advantage of those new geoprocessing tools if you have both Pro and Desktop installed. Take a look at this Help page Python in ArcGIS Pro. To learn more about calling Windows applications from Python, take a look at the built-in subprocess module.

Arcpy: Get route distance and travel time between stops in an ArcMap Network Analysis layer

If you are a user of ArcGIS Network Analyst extension, this post is for you. I am pretty sure many analysts solving routes between multiple stops would like to get some additional information about the solved stops. The route feature created after the solve does contain the information on the total route travel time as well as its distance. However, there is no information about the distance between individual stops in the route.

In other words, if your route has 10 stops, what if you would like to quickly get the distance value from the stop2 to stop7? If you have set up the accumulators in the Route solver properties, you will get those accumulators attributes in the Stops sub layer. This means you will be able to do the calculation manually because you would know that from the route start point, it took 5 minutes to get to stop2 and 18 minutes to get to stop7, so the travel time between the stop2 and stop7 is 13 minutes (18 min minus 5 min).

To avoid doing those tedious calculations, I’ve written a tiny code snippet with arcpy that you can wrap into an ArcGIS Python add-in. After installing the add-in, you will be able to select two arbitrary route stops and after calling the code, a message window will show you the distance and travel time between the stops. This code is supposed to be wrapped into a Python add-in, but can also be executed as a standalone script tool with minor modifications. This code assumes that the route has been already solved and there are accumulators associated with the route solver.

If you would like to customize this tool making it more flexible by reading the accumulators and getting their types and units, take a look at the RouteSolverProperties arcpy object as well as the network dataset Describe object properties.

This is how this code runs in ArcMap with the Python add-in installed:

distance_between_route_stops

The code: