I'm trying to get Geo-HMS "Centroidal Longest Flowpath" to run from within Python.
My current configuration is:
I've generated a python module using the following code:
import arcpy import arcpy.toolbox_code arcpy.toolbox_code.generate_toolbox_module(r'C:\Program Files (x86)\ArcGIS\Desktop10.2\ArcToolbox\Toolboxes\GeoHMS Tools.tbx', r'C:\Program Files (x86)\HEC\HEC-GeoHMS\bin\GeoHMSTools.py' False, False, True)
I then generated a python path file that points to the GeoHMSTools.py module file under the following directory:
C:\Python27\ArcGIS10.2\Lib\site-packages\GeoHMSTools.pth
I'm able to import GeoHMSTools within my Python IDE (Eclipse) as well as within ArcMap Python Interpreter Window and all the tools are visisble. When I try to run Centroidal Longest Flowpath from within Python I receive the following error message after Python crashes:
''' Created on Feb 2, 2016 @author: PeterW ''' import arcpy import GeoHMSTools subbasin = r"E:\Python\Temp\Model02\Model02.gdb\Layers\Subwatershed" centroid = r"E:\Python\Temp\Model02\Model02.gdb\Layers\Centroid" longestflowpath = r"E:\Python\Temp\Model02\Model02.gdb\Layers\LongestFlowPath_2D" centroidallongestflowpath = r"E:\Python\Temp\Model02\Model02.gdb\Layers\CentroidalLongestFlowPath10" GeoHMSTools.CentroidalLongestFlowpath(subbasin, centroid, longestflowpath, centroidallongestflowpath)
Unhandled Exception: System.ArgumentException: The object's type must be __ComObject or derived from __ComObject. Parameter name: o at System.Runtime.InteropServices.Marshal.ReleaseComObject(Object o) at ESRI.APWR.HECGeoHMS10.GPCentroidalLongestFlowPath.Finalize()
Any help in being able to resolve the following will be appreciated.
Solved! Go to Solution.
Hi Cynthia
I eventually landed up re-writing the Centroidal Longest Flowpath Tool within Python. I've added the code below if you'd like to use it.
Please note that you will need Python Pathlib Package or other wise replace it with os.path.join.
Also note that the following feature class needs to be within the input file geodatabase:
''' Created on Feb 23, 2016 Determine CentroidalongestFlowPath @author: PeterW ''' # import site-packages and modules from pathlib import Path import arcpy # set input and output arguments fgdb = Path(r"E:\Projects\2016\G112491\ArcHydro\ArcHydro\Northern\Model01\Model01.gdb") # set environment variables arcpy.env.overwriteOutput = True # add centroidalfl field to longestflowpath_2d def centroidal_flow_line_field(fgdb): longestflowpath_2d = "{0}\\{1}".format(Path(fgdb, "Layers"), "LongestFlowPath_2D") fieldname = "CentroidalFL" fields = arcpy.ListFields(longestflowpath_2d) for field in fields: if field.name.lower() == fieldname.lower(): arcpy.DeleteField_management(longestflowpath_2d, fieldname) arcpy.AddField_management(longestflowpath_2d, fieldname, "DOUBLE") else: arcpy.AddField_management(longestflowpath_2d, fieldname, "DOUBLE") return longestflowpath_2d longestflowpath_2d = centroidal_flow_line_field(fgdb) # flip longestflowpath_2d downstream to upstream def flip_longestflowpath(longestflowpath_2d): arcpy.FlipLine_edit(longestflowpath_2d) flip_longestflowpath(longestflowpath_2d) # determine centroidal longest flowpath length and point geometry def centroidal_flow_line_length(fgdb, longestflowpath_2d): centroid = "{0}\\{1}".format(Path(fgdb, "Layers"), "Centroid") centroidalfl_geometry = [] with arcpy.da.SearchCursor(centroid, ["SHAPE@", "DrainID"]) as scur: # @UndefinedVariable for row1 in scur: with arcpy.da.UpdateCursor(longestflowpath_2d, ["SHAPE@", "DrainID", "CentroidalFL"]) as upcur: # @UndefinedVariable for row2 in upcur: if row1[1] == row2[1]: tpl = row2[0].queryPointAndDistance(row1[0], False) row2[2] = tpl[1] upcur.updateRow(row2) centroidalfl_geometry.append(tpl[0]) return centroidalfl_geometry centroidalfl_geometry = centroidal_flow_line_length(fgdb, longestflowpath_2d) # flip longestflowpath_2d upstream to downstream flip_longestflowpath(longestflowpath_2d) # generate centroidal longest flowpath polylines from longestflowpath_2d def centroidal_flow_line_polyline(fgdb, longestflowpath_2d, centroidalfl_geometry): centroidalfl_polyline = "{0}\\{1}".format(Path(fgdb, "Layers"), "CentroidalFL") arcpy.SplitLineAtPoint_management(longestflowpath_2d, centroidalfl_geometry, centroidalfl_polyline) centroidalfl_length = [] with arcpy.da.SearchCursor(longestflowpath_2d, ["CentroidalFL"]) as scur: # @UndefinedVariable for row in scur: centroidalfl_length.append("{0:.6f}".format(row[0])) with arcpy.da.UpdateCursor(centroidalfl_polyline, ["SHAPE@LENGTH"]) as upcur: # @UndefinedVariable for row in upcur: shape_length = "{0:.6f}".format(row[0]) if shape_length not in centroidalfl_length: upcur.deleteRow() centroidal_flow_line_polyline(fgdb, longestflowpath_2d, centroidalfl_geometry)
Hope the following helps
I also have this question. So far this is what I have:
arcpy.ImportToolbox(r"Toolboxes\System Toolboxes\GeoHMS Tools.tbx")
arcpy.BasinCentroid_geohms("Center of gravity", "Subbasin", "Centroid")
arcpy.CentroidalLongestFlowpath_geohms("Subbasin", "Centroid", "Longest", "Longest_Centroid")
The "Longest" flowpath layer was created correctly with ArcHydro. I cannot get the Python codes to work and create a longest flowpath layer with HEC-GeoHMS. I think this is where the error is coming in. Any help from Esri?
Hi Cynthia
I eventually landed up re-writing the Centroidal Longest Flowpath Tool within Python. I've added the code below if you'd like to use it.
Please note that you will need Python Pathlib Package or other wise replace it with os.path.join.
Also note that the following feature class needs to be within the input file geodatabase:
''' Created on Feb 23, 2016 Determine CentroidalongestFlowPath @author: PeterW ''' # import site-packages and modules from pathlib import Path import arcpy # set input and output arguments fgdb = Path(r"E:\Projects\2016\G112491\ArcHydro\ArcHydro\Northern\Model01\Model01.gdb") # set environment variables arcpy.env.overwriteOutput = True # add centroidalfl field to longestflowpath_2d def centroidal_flow_line_field(fgdb): longestflowpath_2d = "{0}\\{1}".format(Path(fgdb, "Layers"), "LongestFlowPath_2D") fieldname = "CentroidalFL" fields = arcpy.ListFields(longestflowpath_2d) for field in fields: if field.name.lower() == fieldname.lower(): arcpy.DeleteField_management(longestflowpath_2d, fieldname) arcpy.AddField_management(longestflowpath_2d, fieldname, "DOUBLE") else: arcpy.AddField_management(longestflowpath_2d, fieldname, "DOUBLE") return longestflowpath_2d longestflowpath_2d = centroidal_flow_line_field(fgdb) # flip longestflowpath_2d downstream to upstream def flip_longestflowpath(longestflowpath_2d): arcpy.FlipLine_edit(longestflowpath_2d) flip_longestflowpath(longestflowpath_2d) # determine centroidal longest flowpath length and point geometry def centroidal_flow_line_length(fgdb, longestflowpath_2d): centroid = "{0}\\{1}".format(Path(fgdb, "Layers"), "Centroid") centroidalfl_geometry = [] with arcpy.da.SearchCursor(centroid, ["SHAPE@", "DrainID"]) as scur: # @UndefinedVariable for row1 in scur: with arcpy.da.UpdateCursor(longestflowpath_2d, ["SHAPE@", "DrainID", "CentroidalFL"]) as upcur: # @UndefinedVariable for row2 in upcur: if row1[1] == row2[1]: tpl = row2[0].queryPointAndDistance(row1[0], False) row2[2] = tpl[1] upcur.updateRow(row2) centroidalfl_geometry.append(tpl[0]) return centroidalfl_geometry centroidalfl_geometry = centroidal_flow_line_length(fgdb, longestflowpath_2d) # flip longestflowpath_2d upstream to downstream flip_longestflowpath(longestflowpath_2d) # generate centroidal longest flowpath polylines from longestflowpath_2d def centroidal_flow_line_polyline(fgdb, longestflowpath_2d, centroidalfl_geometry): centroidalfl_polyline = "{0}\\{1}".format(Path(fgdb, "Layers"), "CentroidalFL") arcpy.SplitLineAtPoint_management(longestflowpath_2d, centroidalfl_geometry, centroidalfl_polyline) centroidalfl_length = [] with arcpy.da.SearchCursor(longestflowpath_2d, ["CentroidalFL"]) as scur: # @UndefinedVariable for row in scur: centroidalfl_length.append("{0:.6f}".format(row[0])) with arcpy.da.UpdateCursor(centroidalfl_polyline, ["SHAPE@LENGTH"]) as upcur: # @UndefinedVariable for row in upcur: shape_length = "{0:.6f}".format(row[0]) if shape_length not in centroidalfl_length: upcur.deleteRow() centroidal_flow_line_polyline(fgdb, longestflowpath_2d, centroidalfl_geometry)
Hope the following helps
Hi, I have the same problem. Does anyone find a solution?