def getLogRasterStatistic(self, Characteristic): ''' This method returns a the natural log of values returned from Raster Statistic. This is only used for TWI at the moment. Original outline for this code was pulled from getPointFeatureDensity. ''' ML = None result = {Characteristic.Name: None} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) if not ML.Activated: raise Exception("Map Layer could not be activated.") rastStat = super(StreamStatsNationalOps, self).getRasterStatistic(ML.Dataset, self.mask, "MEAN") result[Characteristic.Name] = np.log(rastStat) except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm("Anthops percentImpervious" + tb, "ERROR", 71) result[Characteristic.Name] = None finally: #Cleans up workspace ML = None return result
def getPointFeatureDensity(self, Characteristic): ''' Computes feature count per unit area. ''' ML = None result = {Characteristic.Name: 0} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) if not ML.Activated: raise Exception("Map Layer could not be activated.") totArea = self.getAreaSqMeter( self.mask) * Shared.CF_SQMETERS2SQKILOMETER count = super(StreamStatsNationalOps, self).getFeatureCount(ML.Dataset, self.mask) result[Characteristic.Name] = count / totArea except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm( "getPointFeatureDensity " + Characteristic.Name + " " + tb, "ERROR", 71) result[Characteristic.Name] = float('nan') finally: #Cleans up workspace ML = None return result
def getRasterPercent(self, Characteristic): ''' Computes the percent of a whole. Useful for calculating percent impervious from the NLCD data, percent irrigated agriculture using MIRAD data, and NWALT data. ''' ML = None result = {Characteristic.Name: None} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) if not ML.Activated: raise Exception("Map Layer could not be activated.") result[Characteristic.Name] = super( StreamStatsNationalOps, self).getRasterPercent( ML.Dataset, self.mask, Characteristic.ClassCodes ) * Characteristic.MultiplicationFactor except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm("Anthops percentImpervious" + tb, "ERROR", 71) result[Characteristic.Name] = None finally: #Cleans up workspace ML = None return result
def getFeatureStatistic(self, Characteristic): ''' Computes feature stat. ''' ML = None result = {Characteristic.Name: 0} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) if not ML.Activated: raise Exception("Map Layer could not be activated.") tot = super(StreamStatsNationalOps, self).getFeatureStatistic(ML.Dataset, self.mask, Characteristic.Method, Characteristic.QueryField, Characteristic.WhereClause) result[Characteristic.Name] = tot[Characteristic.QueryField][ Characteristic.Method] except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm( "getPointFeatureDensity " + Characteristic.Name + " " + tb, "ERROR", 71) result[Characteristic.Name] = float('nan') finally: #Cleans up workspace ML = None return result
def getStoragePerUnitArea(self, Characteristic): ''' Calculates the Storage per unit area. Is used for computing things such as computing the Reservoir storage from National Inventory of Dams (NID) ''' ML = None result = {Characteristic.Name: 0} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) ML_sr = arcpy.Describe(ML.Dataset).spatialReference arcpy.env.workspace = self._TempLocation if not ML.Activated: raise Exception("Map Layer could not be activated.") #This calculation should probably be changed depending on what is needed. # I'm guessing this should be a function in Shared.py totArea = self.getAreaSqMeter( self.mask ) * Shared.CF_SQMETERS2SQKILOMETER #Put ConversionFactor here? #spatial overlay #cursor and sum with arcpy.da.SearchCursor(self.spatialOverlay( ML.Dataset, self.mask), Characteristic.QueryField, spatial_reference=ML_sr) as source_curs: for row in source_curs: val = WIMLib.Shared.try_parse(row[0], None) result[Characteristic.Name] += float( val ) * Shared.CF_ACR2SQKILOMETER / totArea #Put ConversionFactor here? #next #end with except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm("ReservoirStorage" + tb, "ERROR", 71) result[Characteristic.Name] = float('nan') finally: #Cleans up workspace ML = None return result
def getPrismStatistic(self, Characteristic): #Computes statistic for prism data. Changed by JWX. Indent block did not work. result = {Characteristic.Name: None} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) if not ML.Activated: raise Exception("Map Layer could not be activated.") timeRange = [ dt.strptime(str(x), '%m-%d-%Y') for x in Characteristic.TimeRange.split(';') ] result[Characteristic.Name] = super( StreamStatsNationalOps, self).getPrismStatistic(ML.Dataset, self.mask, Characteristic.Method, timeRange, Characteristic.TimeMethod, Characteristic.Data) except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm( "getPrismStatistic error" + tb + " " + Characteristic.Name, "ERROR", 71) result[Characteristic.Name] = None finally: #Cleans up workspace ML = None return result
def getRasterStatistic(self, Characteristic): ''' Calculates the raster statistics using various passed methods such as Mean, Median, Mode, Max, and Min. ''' ML = None result = {Characteristic.Name: None} try: self._sm("Computing " + Characteristic.Name) #ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0])) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0]), "", self.mask) if not ML.Activated: raise Exception("Map Layer could not be activated.") result[Characteristic.Name] = super( StreamStatsNationalOps, self).getRasterStatistic( ML.Dataset, self.mask, Characteristic.Method ) * Characteristic.MultiplicationFactor result[Characteristic.Name + 'up'] = super( StreamStatsNationalOps, self).getRasterStatistic( ML.Dataset, self.mask3, Characteristic.Method ) * Characteristic.MultiplicationFactor except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm( "getRasterStatistic error" + tb + " " + Characteristic.Name, "ERROR", 71) result[Characteristic.Name] = None finally: #Cleans up workspace ML = None return result
def Delineate(self, PourPoint, inmask=None): #http://pro.arcgis.com/en/pro-app/tool-reference/spatial-analyst/watershed.htm fdr = None sr = None mask = None datasetPath = None featurePath = None outWatershedRaster = None upCatch = None dstemp = None downCatch = None try: catchments = Config()["catchment"] arcpy.env.workspace = self._TempLocation self._sm("Delineating catchment") fdr = MapLayer(MapLayerDef("fdr"), "", PourPoint) if not fdr.Activated: raise Exception("Flow direction could not be activated.") fac = MapLayer(MapLayerDef("fac"), fdr.TileID) if not fac.Activated: raise Exception("Flow accumulation could not be activated.") sr = fdr.spatialreference if inmask is not None: mask = self.ProjectFeature(inmask, sr) datasetPath = arcpy.CreateFileGDB_management( self._WorkspaceDirectory, self.WorkspaceID + '.gdb')[0] featurePath = arcpy.CreateFeatureDataset_management( datasetPath, 'Layers', sr)[0] self._sm("creating workspace environment. " + datasetPath) arcpy.CheckOutExtension("Spatial") self._sm("Starting Delineation") arcpy.env.extent = arcpy.Describe(mask).extent #Build snap pour point then use it for watershed. # Pour point search distance of 60 m is equal to two cells. outSnapPour = SnapPourPoint(PourPoint, fac.Dataset, 60) outWatershedRaster = Watershed(fdr.Dataset, outSnapPour) upCatch = os.path.join(featurePath, catchments["upstream"]) arcpy.RasterToPolygon_conversion(outWatershedRaster, upCatch, "NO_SIMPLIFY") #strip downstream catchment from mask dstemp = arcpy.Erase_analysis(mask, upCatch, "dstemp") downCatch = self.__removePolygonHoles(dstemp, featurePath, catchments["downstream"]) self._sm(arcpy.GetMessages(), 'AHMSG') self._sm("Finished") except: tb = traceback.format_exc() self._sm("Delineation Error " + tb, "ERROR") finally: arcpy.CheckInExtension("Spatial") #Local cleanup if fdr is not None: del fdr if sr is not None: del sr if mask is not None: arcpy.Delete_management(mask) if dstemp is not None: arcpy.Delete_management(dstemp) dstemp = None for raster in arcpy.ListRasters("*", "GRID"): arcpy.Delete_management(raster) del raster raster = None if datasetPath is not None: del datasetPath if featurePath is not None: del featurePath if upCatch is not None: del upCatch upCatch = None if downCatch is not None: del downCatch downCatch = None arcpy.env.extent = ""
def getVectorDensity(self, Characteristic): ''' Is a modification of getPointFeatureDensity. Initially created to calculate the percent of dams per stream. This method is a mash-up of prior work done within this method and the getFeatureStatistic Method found in SpatialOps.py. Mashed-up by JWX. ''' map = [] analysisFeatures = [] ML = None result = {Characteristic.Name: 0} try: self._sm("Computing " + Characteristic.Name) ML = MapLayer(MapLayerDef(Characteristic.MapLayers[0]), "", self.mask) if not ML.Activated: raise Exception("Map Layer could not be activated.") spOverlayWhole = self.spatialOverlay( ML.Dataset, self.mask, "INTERSECTS") #Added back after sumMain was removed analysisFeatures.append(spOverlayWhole[0]) #Create query queryField = "{}".format( Characteristic.Field ) #Generalized to pass whatever field needed operator = Characteristic.Operator #Generalized to whatever operator e.g. =, LIKE, != if operator == "LIKE": #If operator = LIKE, flanking "%" are needed keyword = "'%{}%'".format(Characteristic.Keyword) else: keyword = Characteristic.Keyword query = "{} {} {}".format(queryField, operator, keyword) #Build query #Create sub-set feature class using query arcpy.MakeFeatureLayer_management( spOverlayWhole, "Subsetlayer") #Make feature layer arcpy.SelectLayerByAttribute_management( "Subsetlayer", "NEW_SELECTION", query) #Carry out selection outName = os.path.join( self._TempLocation, "vdtmp.shp") #SHP has to be included for proper function arcpy.CopyFeatures_management( "Subsetlayer", outName) #Copy out features to avoid selection errors arcpy.SelectLayerByAttribute_management("Subsetlayer", "CLEAR_SELECTION") if arcpy.GetCount_management(outName).getOutput( 0) == "0": #Catch if the dataset is blank self._sm( "Warning: Subset feature is blank. Zero will be substituded." ) result[Characteristic.Name] = 0 #If blank, result is zero else: analysisFeatures.append(outName) #Get methods and field for analysis statisticRules = Characteristic.Method Fields = Characteristic.MethField #Method operation field (newly added to config.json) #methods = [x.strip() for x in statisticRules.split(';')] #Could be used to scale the method section #Fields = [x.strip() for x in fieldStr.split(';')] #Could be used to scale the fields section map.append([Fields, statisticRules]) #Build statistics statement resultCalculation = [] #AN ARRAY TO CAPTURE VALUES*** for feaure in analysisFeatures: #NEEDED CALCULATE EVERYTHING*** tblevalue = arcpy.Statistics_analysis( feaure, os.path.join(self._TempLocation, "aftmp"), map) mappedFeilds = [x[1] + "_" + x[0] for x in map] cursor = arcpy.da.SearchCursor(tblevalue, mappedFeilds) for row in cursor: resultCalculation.append(row[0]) #Generate values for results if len(analysisFeatures) == 1: #Catch streams only instances result[Characteristic.Name] = 0 else: if resultCalculation[0] == 0: #Catch canal only instances result[Characteristic.Name] = 100 else: result[Characteristic.Name] = ( resultCalculation[1] / resultCalculation[0]) * 100 #Otherwise carry out math except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm("getVectorDensity " + Characteristic.Name + " " + tb, "ERROR", 71) result[Characteristic.Name] = float('nan') finally: #Cleans up workspace ML = None arcpy.SelectLayerByAttribute_management( "Subsetlayer", "CLEAR_SELECTION") #This was added by JWX return result
def getNIDDistrubanceIndex(self, Characteristic): # #DI_d,g = sum (Storage_d*DA_d/DA_t)/ # (P*DA_t) #Where: DI_d,g - Dams Disturbance Index for gage # Storage_d - Storage at dam, in acre feet # DA_d - Drainage area at dam, in acres # DA_t - Total Drainage area at gage, in acres # P - Average Annual Precipitation, in feet # result = {Characteristic.Name: 0} try: self._sm("Computing " + Characteristic.Name) nidML = MapLayer(MapLayerDef( Characteristic.MapLayers[0])) #USGS_NID_2018 precipML = MapLayer(MapLayerDef( Characteristic.MapLayers[1])) #Precip if not nidML.Activated or not precipML.Activated: raise Exception("Map Layer could not be activated.") P = super(StreamStatsNationalOps, self).getRasterStatistic( precipML.Dataset, self.mask2, None) * 0.003280841666667 #mm2foot DA_t = self.getAreaSqMeter( self.mask2) * 0.000247105 #Sqrmeter2Acre nidFeatures = arcpy.MakeFeatureLayer_management( self.spatialOverlay(nidML.Dataset, self.mask2), "nidfeatures") #join tables for jn in Characteristic.JoinTables[0]: jnfld = Characteristic.JoinField[: 10] #trim 8 char to account for nidFeatures being a shp (fields are limited to 8 char length) arcpy.AddJoin_management( nidFeatures, jnfld, os.path.join(nidML.Path, nidML.DatasetName, jn['table']), jn['key'], 'KEEP_COMMON') #next join fields = [ fld['table'] + "." + fld['QueryField'] for fld in Characteristic.JoinTables[0] ] sum = 0 with arcpy.da.SearchCursor(nidFeatures, fields) as source_curs: for row in source_curs: Storage_d = row[0] #Acre_feet DA_d = row[1] #Acre sum += Storage_d * (DA_d / DA_t) #next #end with result[Characteristic.Name] = sum / (P * DA_t) except: tb = traceback.format_exc() self._sm(arcpy.GetMessages(), 'GP') self._sm( "getPointFeatureDensity " + Characteristic.Name + " " + tb, "ERROR", 71) result[Characteristic.Name] = float('nan') finally: #Cleans up workspace ML = None return result