Friday, 19 June 2026

ArcGIS Pro – Clone a virtual Python environment for offline machines

In ArcGIS Pro you need to create a new virtual Python environment in order to install additional Python packages. How can you set up that virtual environment on a machine that has no Internet access?

The first surprise is that creating a new virtual environment requires Internet access at all — I had assumed the existing Python environment would simply be copied locally. When creating a new virtual environment, ArcGIS Pro attempts to download Python packages, presumably to install the most recent available versions.

The simplest solution seems to be: create the new virtual environment on a machine that has Internet access, install all additional packages you need there, then copy that environment folder to the offline machine.

Prerequisite: ArcGIS Pro must be the same version on both machines — in other words, the Python runtime must match. I don't know how exact that version match must be.

 Steps:

1) Create a new Python environment in ArcGIS Pro.

2) Install the additional packages you require.

3) The newly created environment is placed in the user's folder:

C:\Users\<username>\AppData\Local\ESRI\conda\envs

Zip the subfolder that corresponds to the environment you want, copy the zip file to the target (offline) machine, and extract it into the same folder there.


 

See also: Solved: How to clone the ArcGIS Pro 3 Python environment? - Esri Community

Thursday, 28 November 2024

Register as 'versioned' failed - ORA-02327 cannot create index on expression with data type ADT

I got the message "Register as 'versioned' failed - ORA-02327 cannot create index on expression with data type ADT" a while ago when I disabled versioning and tried to re-enable it.

As a workaround, I found that I had to delete the feature class mentioned in the error message and re-import it from a file geodatabase.

The problem is that with IMPORT you lose the globalid. But simply deleting and copying and pasting from the FGDB didn't solve the problem.

The message has now reappeared - displayed again but with a different Oracle schema. In the meantime we changed the Oracle version (from 12 to 19).

Deleting the feature classes (all part of a feature dataset) and re-importing them from FGDB didn't help.  When I copied the feature class from the dataset to a location outside of the dataset, I could sometimes register the feature class as versioned - but not always.

The solution was to use another computer to enable versioning. I don't know why this solved the problem - we have the same version of ArcGIS installed on both machines. The only difference I noticed is that the computer where versioning activation was successful did not have a language pack installed.

One more thing to mention: I first did exactly the same thing in our test database and didn't encounter any problems when re-enabling versioning.

Tuesday, 15 March 2022

ArcCatalog - deleted feature class reappears (Enterprise Geodatabase)

I tried to delete Oracle views in ArcCatalog but as soons as I reconnected the feature class reappeared in ArcCatalog.

It seems that if the view is invalid in Oracle ArcCatalog can't delete it. You need to modify the view so that it becomes valid again before deleting.

ArcMap/ArcCatalog 10.7.1, Oracle 11g

Geonis Interlis Export - ORA-24550: signal received: Unhandled exception: Code=e0434352 Flags=1 - revisted

Coming back to a post from 2019:

ORA-24550: signal received: Unhandled exception: Code=e0434352 Flags=1

The message doesnt help that much and hides the error message generated by the application. The message seems to be part of some kind of diagnostics which is enabled by default in some circumstances in Oracle client. It can be turned off by adding the following setting to sqlnet.ora

DIAG_SIGHANDLER_ENABLED=FALSE

After turning it off I got a more helpful error stack trace:

Unhandled Exception: GEONIS.Core.ErrorHandling.GTranslateableException: Could not open Table [VMG.VMG_V_VER_FLA_ART] ---> System.Runtime.InteropServices.COMException: DBMS-Tabelle nicht gefunden [ORA-24372: Ungültiges Objekt für Beschreibung]

   at ESRI.ArcGIS.Geodatabase.IFeatureWorkspace.OpenTable(String Name)

   ....


Tuesday, 21 September 2021

Hide single features in ArcMap

Here is a Python tool to hide selected features in ArcMap and to bring them back to screen. Useful if you need to create a screenshot / printout but want to hide certain features but not a whole layer. The tool applies a definition filter to "hide" selected features (across multiple layers) and removes the filters to display the features again. Filter condition is added to existing query.

Initial idea found on gis.stackexchange:

https://gis.stackexchange.com/questions/368848/creating-definition-query-from-selected-features-using-arcgis-pro

First the toolbox definition - save as PYT file:

 # -*- coding: utf-8 -*-  
 """  
 Created on Fri Feb 28 08:49:34 2020  
 """  
 import arcpy , m_main_layer  
 class Toolbox(object):  
   def __init__(self):  
     """Define the toolbox (the name of the toolbox is the name of the .pyt file)."""  
     self.label = "My Toolbox"  
     self.alias = ""  
     # List of tool classes associated with this toolbox  
     self.tools = [FeatureOff, FeatureOn]  
 class FeatureOff(object):  
   def __init__(self):  
     """Define the tool (tool name is the name of the class)."""  
     self.label = "Hide selected features"  
     self.description = "Hides selected features by applying a layer definition query"  
     self.canRunInBackground = False  
   def getParameterInfo(self):  
     """Define parameter definitions"""  
     return  
   def isLicensed(self):  
     """Set whether tool is licensed to execute."""  
     return True  
   def updateParameters(self, parameters):  
     """Modify the values and properties of parameters before internal  
     validation is performed. This method is called whenever a parameter  
     has been changed."""      
     return  
   def updateMessages(self, parameters):  
     """Modify the messages created by internal validation for each tool  
     parameter. This method is called after internal validation."""  
     return  
   def execute(self, parameters, messages):      
     reload(m_main_layer)       
     m_main_layer.main_off()  
     return  
 class FeatureOn(object):  
   def __init__(self):  
     """Define the tool (tool name is the name of the class)."""  
     self.label = "Display hidden features"  
     self.description = "displays hidden features by removing layer definition query"  
     self.canRunInBackground = False  
   def getParameterInfo(self):  
     """Define parameter definitions"""  
     return  
   def isLicensed(self):  
     """Set whether tool is licensed to execute."""  
     return True  
   def updateParameters(self, parameters):  
     """Modify the values and properties of parameters before internal  
     validation is performed. This method is called whenever a parameter  
     has been changed."""      
     return  
   def updateMessages(self, parameters):  
     """Modify the messages created by internal validation for each tool  
     parameter. This method is called after internal validation."""  
     return  
   def execute(self, parameters, messages):      
     reload(m_main_layer)       
     m_main_layer.main_on()  
     return            
Here the main Python script:
 # -*- coding: utf-8 -*-  
 """  
 Created on Fri Mar 20 09:11:37 2020  
 """  
 # -*- coding: utf-8 -*-  
 import arcpy  
 # mark start of query condition  
 # comments such as /* -- */ do not work with FGDB  
 # therefore we add a dummy condition as start marker  
 query_start_marker = "'A'='A'"  
 query_concat = " AND "  
 # max value might be different for each database system in use:  
 max_num_selected_features_per_layer = 999  
 def remove_filter_features(lyr):    
   if not lyr.isFeatureLayer:  
     return   
   desc = arcpy.Describe(lyr.name)      
   query = lyr.definitionQuery  
   start = query.find(query_start_marker)         
   if start >= 0:  
     query_front = query[:start]                 
     len_query_conact = len(query_concat)  
     if len(query_front) > len_query_conact and query_front[-len_query_conact:] == query_concat:  
       query_front = query_front[:-len_query_conact]              
     lyr.definitionQuery = query_front  
 def apply_filter_selected_features(lyr):    
   if not lyr.isFeatureLayer:  
     return                
   desc = arcpy.Describe(lyr.name)        
   if desc.FIDSet != '':                   
     fid_list = desc.FIDSet.split(";")  
     if len(fid_list) > max_num_selected_features_per_layer:  
       arcpy.AddMessage("Too many features selected ({0}), max: {1}.".format(len(fid_list),max_num_selected_features_per_layer))  
       return  
     query = ' {} NOT IN ({}) '.format(desc.OIDFieldName, ",".join(fid_list))      
     existing_query = lyr.definitionQuery  
     if existing_query:  
       query = existing_query + query_concat + query_start_marker+ ' AND ' + query  
     else:  
       query = query_start_marker + ' AND ' + query      
     lyr.definitionQuery = query      
     arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")  
 def main_off():          
   arcpy.AddMessage("hide selected features....")  
   mxd = arcpy.mapping.MapDocument("CURRENT")       
   df = arcpy.mapping.ListDataFrames(mxd)[0]    
   for l in arcpy.mapping.ListLayers(df):  
     apply_filter_selected_features(l)  
   arcpy.AddMessage("hide selected features....finished")  
 def main_on():  
   arcpy.AddMessage("display hidden features....")  
   mxd = arcpy.mapping.MapDocument("CURRENT")       
   df = arcpy.mapping.ListDataFrames(mxd)[0]    
   for l in arcpy.mapping.ListLayers(df):  
     remove_filter_features(l)  
   arcpy.RefreshActiveView()            
   arcpy.AddMessage("display hidden features....finished")  

Example:

select features...
...hidden...


...bringing them back to screen...










Thursday, 19 December 2019

ArcGISServer / WebOffice - Reprojecting WMS service

It seems neither ArcGISServer nor VertiGIS WebOffice allow reprojecting a WMS service. However, that is what we needed as the WMS service provider from across the border did not want to add support for another coordinate system (epgs:2056) to its service. 

First option we looked into was MapProxy . It's relatively easy to install and to get a basic sample up and running. But it seems integration into IIS is not straightforward. I didn't bother to invest more time investigating this option any further. Fortunately, GeoServer also supports reprojecting WMS services - and surprisingly it was very easy to install and to get it to work. 

As we use VertiGIS WebOffice we have already Tomcat running. GeoServer installation is basically downloading the right file (Web-Archive), unzipping it and copying the resulting WAR file in to Tomcats WebApp folder and finally restarting Tomcat. Second step is to set up the WMS service - again straightforward as GeoServer comes with an easy to use and self-explaining web-interface.


Map project in epsg:2056, WMS service provided in epsg:25832 but reprojected by GeoServer

Monday, 21 October 2019

Geonis form with SQL

I added the following SQL statement to a Geonis form

 <edit title="Objekt" width="150">  
 <select>  
 select name_nummer as name from u_ele_trasseeabschnitt where globalid = [REF_FEAT_GID]  
 union all  
 select name_nummer as name from u_ele_strangabschnitt where globalid = [REF_FEAT_GID]  
 union all  
 select name || ', ' || u_tplnr from ele_tragwerk where globalid = [REF_FEAT_GID]  
 union all  
 select name || ', ' || u_tplnr from ele_schacht where globalid = [REF_FEAT_GID]  
 </select>  
 </edit>       

but I didn't get any results. Turns out that one needs to use the CONCAT command instead:

 <edit title="Objekt" width="150">  
 <select>  
 select name_nummer from u_ele_trasseeabschnitt where globalid = [REF_FEAT_GID]  
 union all  
 select name_nummer from u_ele_strangabschnitt where globalid = [REF_FEAT_GID]  
 union all  
 select concat(name, concat(', ', u_tplnr)) as name_nummer from ele_tragwerk where globalid = [REF_FEAT_GID]  
 union all  
 select concat(name, concat(', ', u_tplnr)) as name_nummer from ele_schacht where globalid = [REF_FEAT_GID]                                     
 </select>  
 </edit>                 

Geonis 2017.0