def CompareSpatialRef(in_Data, in_Template): sr_In = arcpy.Describe(in_Data).spatialReference sr_Out = arcpy.Describe(in_Template).spatialReference srString_In = sr_In.exporttostring() srString_Out = sr_Out.exporttostring() gcsString_In = sr_In.GCS.exporttostring() gcsString_Out = sr_Out.GCS.exporttostring() if srString_In == srString_Out: reproject = 0 transform = 0 geoTrans = "" else: reproject = 1 if reproject == 1: if gcsString_In == gcsString_Out: transform = 0 geoTrans = "" else: transList = arcpy.ListTransformations(sr_In, sr_Out) if len(transList) == 0: transform = 0 geoTrans = "" else: transform = 1 geoTrans = transList[0] return (sr_In, sr_Out, reproject, transform, geoTrans)
def get_clip_region(clip_area_wkt, out_coordinate_system=None): """Creates and returns an extent representing the clip region from WKT. :param clip_area_wkt: Well-known text representing clip extent :param out_coordinate_system: The coordinate system of the output extent :rtype : arcpy.Extent """ import arcpy # WKT coordinates for each task are always WGS84. gcs_sr = get_spatial_reference(4326) clip_area = from_wkt(clip_area_wkt, gcs_sr) if not clip_area.area > 0: clip_area = from_wkt( 'POLYGON ((-180 -90, -180 90, 180 90, 180 -90, -180 -90))', gcs_sr) if out_coordinate_system: out_sr = get_spatial_reference(int(out_coordinate_system)) if not out_sr.name == gcs_sr.name: try: geo_transformation = arcpy.ListTransformations(gcs_sr, out_sr)[0] clip_area = clip_area.projectAs(out_sr, geo_transformation) except AttributeError: clip_area = clip_area.projectAs(out_sr) except IndexError: clip_area = clip_area.projectAs(out_sr) return clip_area.extent
def reprojectGeoDEM(inputDEM, outputDEM): from LUCI_SEEA.lib.external import utm log.info("DEM has geographic coordinate system. Reprojecting...") DEMSpatRef = arcpy.Describe(inputDEM).SpatialReference DEMExtent = arcpy.Describe(inputDEM).extent # Find midpoint of raster midPointX = DEMExtent.XMin + (DEMExtent.XMax - DEMExtent.XMin) / 2 midPointY = DEMExtent.YMin + (DEMExtent.YMax - DEMExtent.YMin) / 2 # Find out which UTM zone the DEM should be projected to northing, easting, zone, letter = utm.from_latlon(midPointY, midPointX) if letter >= "N": northSouth = "N" else: northSouth = "S" # Create the new projected coordinate system projSpatRef = arcpy.SpatialReference("WGS 1984 UTM Zone " + str(zone) + northSouth) # Obtain the transformation string to transform from GCS to PCS transformation = arcpy.ListTransformations(DEMSpatRef, projSpatRef, DEMExtent)[0] # Reproject DEM to Projected Coord System arcpy.ProjectRaster_management(inputDEMRaster, outputDEM, projSpatRef, geographic_transform=transformation) # Update coord system DEMSpatRef = arcpy.Describe(outputDEM).SpatialReference log.info("DEM coordinate system is now " + DEMSpatRef.Name)
def ProjectToMatch(in_Feats, in_Template, out_Feats): '''Check if input features and template data have same spatial reference. If so, make a copy. If not, reproject features to match template. Parameters: in_Feats = input features to be reprojected or copied in_Template = dataset used to determine desired spatial reference out_Feats = output features resulting from copy or reprojection ''' srFeats = arcpy.Describe(in_Feats).spatialReference srTemplate = arcpy.Describe(in_Template).spatialReference if srFeats.Name == srTemplate.Name: printMsg( 'Coordinate systems for features and template data are the same. Copying...' ) arcpy.CopyFeatures_management(in_Feats, out_Feats) else: printMsg('Reprojecting features to match template...') # Check if geographic transformation is needed, and handle accordingly. if srFeats.GCS.Name == srTemplate.GCS.Name: geoTrans = "" printMsg('No geographic transformation needed...') else: transList = arcpy.ListTransformations(srFeats, srTemplate) geoTrans = transList[0] arcpy.Project_management(in_Feats, out_Feats, srTemplate, geoTrans) return out_Feats
def find_transformation(spatialReference, projectedReference): """Figure out a valid transformation from the spatialReference to the desired one""" try: # don't use extent because this gives the same first option as picking in Project Raster tool list = arcpy.ListTransformations(spatialReference, projectedReference) # if no transformations then assum that this means no transformation required return list[0] if len(list) > 0 else "" except: # HACK: assume no transformation if we can't find one return ""
def __get_transformation(self, from_sr, to_sr, extent=None): """ Returns the primary transformation covering a specified extent. """ parameters = {'from_sr': from_sr, 'to_sr': to_sr, 'extent': extent} transformations = arcpy.ListTransformations(**parameters) if transformations: return transformations[0] else: return None
def ProjectExtent(extent, outSystem): sr = arcpy.SpatialReference(extent.spatialReference.wkid) srOut = arcpy.SpatialReference(outSystem) ex = arcpy.Extent(extent.xmin, extent.ymin, extent.xmax, extent.ymax) xfers = arcpy.ListTransformations(sr, srOut) max = ProjectPoint(extent.xmax, extent.ymax, sr, srOut) min = ProjectPoint(extent.xmin, extent.ymin, sr, srOut) projExtent = "{},{},{},{}".format(min.X, min.Y, max.X, max.Y) if "nan" in projExtent: projExtent = "-180, -90, 180, 90" return projExtent
def getTransformMethod(inDataset1, inDataset2): """ Checks to see if a transformation method is needed to project geodatasets. If so, returns the most likely. """ import arcpy # Determine if a transformation method is needed to project datasets (e.g. different datums are used). desc1 = arcpy.Describe(inDataset1) desc2 = arcpy.Describe(inDataset2) spatial1 = desc1.spatialReference spatial2 = desc2.spatialReference transformList = arcpy.ListTransformations(spatial1, spatial2, desc2.extent) if len(transformList) == 0: # if no list is returned; no transformation is required transformMethod = "" else: # default to the first transformation method listed. ESRI documentation indicates this is typically the most suitable transformMethod = transformList[0] return transformMethod
def theProjectWay(): """ This function is currently not used. It is an alternative to the create feature class/append approach currently being used. It is slower because the entire dataset is projected first, and it is less straightforward because it adds the transform method that append seems to know how to handle already. It is better though because it will actually raise trappable errors while Append fails silently... The solution in the other function is to count the resulting records and report issues. """ if targetRef != '': if arcpy.Exists(targetName): arcpy.Delete_management(targetName) inttable = workspace + os.sep + targetName + "_prj" arcpy.env.workspace = workspace xform = None desc = arcpy.Describe(sourceLayer) xforms = arcpy.ListTransformations(desc.spatialReference, targetRef, desc.extent) #if sourceRef.exportToString().find("NAD_1983") > -1 and targetRef.exportToString().find("WGS_1984") > -1: xform = xforms[0] #for xform in xforms: dla.addMessage("Transform: " + xform) try: res = arcpy.Project_management(sourceLayer, inttable, out_coor_system=targetRef, transform_method=xform) except: dla.showTraceback() err = "Unable to project the data to the target spatial reference, please check settings and try projecting manually in ArcGIS" dla.addError(err) return False dla.addMessage("Features projected") view = dla.makeFeatureViewForLayer(dla.workspace, inttable, viewName, whereClause, xmlFields) dla.addMessage("View Created") #except: # arcpy.AddError("Unabled to create feature View " + viewName) count = arcpy.GetCount_management(view).getOutput(0) dla.addMessage(str(count) + " source rows") #sourceRef = getSpatialReference(xmlDoc,"Source") #res = arcpy.CreateFeatureclass_management(workspace,targetName,template=sourceLayer,spatial_reference=targetRef) res = arcpy.CopyFeatures_management(view, targetName) dla.addMessage("Features copied")
def transformation(self, t): if type(self.source) is list: s = self.source esri_output = self.esri_service_output.split(',') elif r"projects/wri-datalab" in self.source or len(self.source) == 0: s = [] else: s = [self.source] esri_output = [self.esri_service_output] for dataset in s: from_desc = arcpy.Describe(dataset) from_srs = from_desc.spatialReference if esri_output[0]: to_srs = arcpy.Describe(esri_output[0]).spatialReference if from_srs.GCS != to_srs.GCS: if not t: logging.debug("No transformation defined") else: extent = from_desc.extent transformations = arcpy.ListTransformations( from_srs, to_srs, extent) if self.transformation not in transformations: logging.info( "Transformation {0!s}: not compatible with in- and output " "spatial reference or extent".format( self.transformation)) t = None del from_desc del to_srs else: t = None self._transformation = t
def _get_extent(self, raster): import arcpy from arcpy import Raster, RasterToNumPyArray, SpatialReference try: transformations = arcpy.ListTransformations( raster.spatialReference, arcpy.SpatialReference(4326)) if len(transformations) > 0: transformation = transformations[0] else: transformation = None extent = json.loads( raster.extent.projectAs(SpatialReference(4326), transformation).JSON) if extent["spatialReference"]["wkid"] is not None: return extent else: raise Exception(f"{extent} contains invalid spatial reference") except Exception as e: log.debug("Handled exception on inferring extent w/ arcpy engine") log.debug(e) return None
def ProjectToMatch(fcTarget, csTemplate): """Project a target feature class to match the coordinate system of a template dataset""" # Get the spatial reference of your target and template feature classes srTarget = arcpy.Describe( fcTarget).spatialReference # This yields an object, not a string srTemplate = arcpy.Describe(csTemplate).spatialReference # Get the geographic coordinate system of your target and template feature classes gcsTarget = srTarget.GCS # This yields an object, not a string gcsTemplate = srTemplate.GCS # Compare coordinate systems and decide what to do from there. if srTarget.Name == srTemplate.Name: printMsg('Coordinate systems match; no need to do anything.') return fcTarget else: printMsg( 'Coordinate systems do not match; proceeding with re-projection.') if fcTarget[-3:] == 'shp': fcTarget_prj = fcTarget[:-4] + "_prj.shp" else: fcTarget_prj = fcTarget + "_prj" if gcsTarget.Name == gcsTemplate.Name: printMsg( 'Datums are the same; no geographic transformation needed.') arcpy.Project_management(fcTarget, fcTarget_prj, srTemplate) else: printMsg( 'Datums do not match; re-projecting with geographic transformation' ) # Get the list of applicable geographic transformations # This is a stupid long list transList = arcpy.ListTransformations(srTarget, srTemplate) # Extract the first item in the list, assumed the appropriate one to use geoTrans = transList[0] # Now perform reprojection with geographic transformation arcpy.Project_management(fcTarget, fcTarget_prj, srTemplate, geoTrans) printMsg("Re-projected data is %s." % fcTarget_prj) return fcTarget_prj
def main(): env.workspace = 'C:\\Temp' #create new folder (if it does not exist already) where to store all processed layers newFold = 'Layers' newpath = os.path.join(env.workspace, 'Layers') if not os.path.exists(newpath): os.makedirs(newpath) #or r'C:\Temp' if you use a single '\' do not forget to add 'r' before the string #or 'C:/Temp' # Allow output to overwrite arcpy.gp.overwriteOutput = True # Local variables: Target_lyr = 'water_Broward.shp' Termite_loc = 'PreTreat03_NoDup2003.shp' LULC_lyr = 'd4_lu_gen_2010.shp' Roads_lyr = 'navteq_broward_streets.shp' TA_Multinet_lyr = 'teleatlas_broward_land_use.shp' #------------------------------------------------------------------------------ #A SpatialReference can be easily created from existing datasets and PRJ files: # #(1) Use a PRJ file as an argument to the SpatialReference class: #prjFile = os.path.join(arcpy.GetInstallInfo()["InstallDir"], # "Coordinate Systems/Geographic Coordinate Systems/North America/NAD 1983.prj") #spatialRef = arcpy.SpatialReference(prjFile) # #(2) Manually define a .prj string #prjFile = 'PROJCS[...]' #spatialRef = arcpy.SpatialReference(prjFile) # #(3) Describe a dataset and access its spatialReference property: #TargetCS = arcpy.Describe(Water_lyr).spatialReference #Geographic transformation - #transformation = 'NAD_1983_To_WGS_1984_1' #If ALL FEATURES need a datum transformation OR NONE of them needs one then #try: # res = arcpy.BatchProject_management(arcpy.ListFeatureClasses('*'), env.workspace, TargetCS, '', # transformation) OR '' instead of transformation # print 'projection of all datasets successful' # else: # print 'failed to project one or more datasets' #except: # print res.getMessages() #------------------------------------------------------------------------------ try: # Define a common target coordinate system desc = arcpy.Describe(Target_lyr) TargetSR = desc.spatialReference # If target layer has no projection defined print a message and stop if TargetSR.Name == "Unknown": arcpy.AddError( Target_lyr + "is used as target layer but has Unknown Projection!") sys.exit('Target Layer Has Unknown Projection!') # Use ListFeatureClasses to generate a list of inputs for inputFC in arcpy.ListFeatureClasses('*'): if inputFC != Target_lyr: # Strip name and extension from a feature class # fileName, fileExtension = os.path.splitext(inputFC) # Input spatial reference inputFC_SR = arcpy.Describe(inputFC).spatialReference # Determine if the input has a defined coordinate system if inputFC_SR.Name == "Unknown": print 'Projecting ' + inputFC + '...' arcpy.DefineProjection_management(inputFC, TargetSR) outFC = os.path.join(newpath, inputFC) # Make a copy of the current layer into the new folder arcpy.CopyFeatures_management(inputFC, outFC) print 'Projected ' + inputFC + ' from Unknown ' + \ ' to ' + TargetSR.Name # Check if current layer and target layer are same TYPE #(i.e. projected and geographic or viceversa) if inputFC_SR.type == TargetSR.type: #SAME TYPE...Check if same projection name: #CASE (1) SAME NAME..create copy and continue if inputFC_SR.Name == TargetSR.Name: outFC = os.path.join(newpath, inputFC) arcpy.CopyFeatures_management(inputFC, outFC) continue #CASE (2) DIFFERENT NAME..check if SAME DATUM OR NOT else: # if they have different names check their datum # (GCS method new in 10.1) if inputFC_SR.GCS.datumName == TargetSR.GCS.datumName: print 'Projecting ' + inputFC + '...' # if datum are the same just project without any transformation outFC = os.path.join(newpath, inputFC) arcpy.Project_management(inputFC, outFC, TargetSR) print 'Projected ' + inputFC + ' from ' + inputFC_SR.Name + \ ' to ' + TargetSR.Name else: # if datum are NOT the same then get transformations # available for your specific study area (based on extent) print 'Projecting ' + inputFC + '...' outlist = arcpy.ListTransformations( inputFC_SR, TargetSR, arcpy.Describe(inputFC).extent) transformation = outlist[0] outFC = os.path.join(newpath, inputFC) arcpy.Project_management(inputFC, outFC, TargetSR, transformation) print 'Projected ' + inputFC + ' from ' + inputFC_SR.Name + \ ' to ' + TargetSR.Name + '\nDatum Transformation: ' + transformation else: #DIFFERENT TYPE...Check if same projection name: #...check if SAME DATUM OR NOT #(GCS method new in 10.1) if inputFC_SR.GCS.datumName == TargetSR.GCS.datumName: print 'Projecting ' + inputFC + '...' #if datum are the same just project without any transformation outFC = os.path.join(newpath, inputFC) arcpy.Project_management(inputFC, outFC, TargetSR) print 'Projected ' + inputFC + ' from ' + inputFC_SR.Name + \ ' to ' + TargetSR.Name else: # if datum are NOT the same then get transformations # available for your specific study area (based on extent) print 'Projecting ' + inputFC + '...' outlist = arcpy.ListTransformations( inputFC_SR, TargetSR, arcpy.Describe(inputFC).extent) transformation = outlist[0] outFC = os.path.join(newpath, inputFC) arcpy.Project_management(inputFC, outFC, TargetSR, transformation) print 'Projected ' + inputFC + ' from ' + inputFC_SR.Name + \ ' to ' + TargetSR.Name + '\nDatum Transformation: ' + transformation else: # if current layer is the same as target layer make a copy and #skip to next iteration outFC = os.path.join(newpath, inputFC) arcpy.CopyFeatures_management(inputFC, outFC) continue print '\n' #------------ #END OF LOOP! #------------ # CALCULATE CENTROID OF POINTS AND CREATE A SQUARE/RECTANGULAR CLIPPING EXTENT # AROUND THAT POINT print 'Calculating centroid of point cloud...' fc = os.path.join(newpath, Termite_loc) shapefieldname = arcpy.Describe(fc).ShapeFieldName # Create search cursor Rows = arcpy.SearchCursor(Termite_loc) # Initialize local variables X_temp = 0.0 Y_temp = 0.0 counter = 0 # Enter for loop for each feature/row for row in Rows: counter = counter + 1 # Create the geometry object 'feat'. Identify the geometry field. feat = row.getValue(shapefieldname) # Use getPart() to return an array of point objects for a particular part of the geometry pnt = feat.getPart() X_temp = X_temp + pnt.X Y_temp = Y_temp + pnt.Y # Calculate centroid of point cloud X_centroid = X_temp / counter Y_centroid = Y_temp / counter # Create an empty feature class from point coords # Set local variables Centroid_pnt = arcpy.Point(X_centroid, Y_centroid) Centroid_pntGeometry = arcpy.PointGeometry(Centroid_pnt, TargetSR) out_name1 = os.path.join(newpath, 'Centroid_buffer.shp') out_name2 = os.path.join(newpath, 'Centroid_buffer_sq.shp') # Specify desired distance distance = '10000 Meters' # Create round buffer print 'Creating round buffer around centroid...' Centroid_buffer = arcpy.Buffer_analysis(Centroid_pntGeometry, out_name1, distance) # Create square buffer print 'Creating square buffer around centroid...' Centroid_buffer_sq = arcpy.FeatureEnvelopeToPolygon_management( Centroid_buffer, out_name2) # Delete the circle buffer...no need to keep it anymore arcpy.Delete_management(Centroid_buffer, '') print '\n' # CLIP ALL FEATURES with the squared buffer area env.workspace = newpath # Loop through a list of feature classes in the desired folder for fc in arcpy.ListFeatureClasses('*'): if fc == 'Centroid_buffer_sq.shp' or fc == Termite_loc: continue # Strip name and extension from a feature class fileName, fileExtension = os.path.splitext(fc) outFC = os.path.join(newpath, fileName + '_Clip' + fileExtension) #Clip each input feature class in the list print 'Clipping ' + fc + ' to square buffer area...' fc_clipped = arcpy.Clip_analysis(fc, Centroid_buffer_sq, outFC, 0.01) #delete original...just keep clipped one arcpy.Delete_management(fc, '') # Rename the clipped file to standard name arcpy.Rename_management(fc_clipped, fc) #END OF LOOP! print '\n' #SELECT FEATURES WITH CERTAIN ATTRIBUTES OF INTEREST # Make a layer from the feature class (temporary layer) arcpy.MakeFeatureLayer_management(LULC_lyr, 'LC_Agric') arcpy.MakeFeatureLayer_management(TA_Multinet_lyr, 'TA_Airport') arcpy.MakeFeatureLayer_management(Roads_lyr, 'NAVTEQ_buff') # Select only those attributes with class agricultural fields (i.e. DESCRIPT = 'AGRICULTURAL') print 'Selecting agricultural features from ' + LULC_lyr arcpy.SelectLayerByAttribute_management( 'LC_Agric', "NEW_SELECTION", " \"DESCRIPT\" = 'AGRICULTURAL' ") # Select only those attributes with feature type Airport Ground (9732) OR Airport Runway (9776) print 'Selecting airport ground & runway features from ' + TA_Multinet_lyr arcpy.SelectLayerByAttribute_management( 'TA_Airport', "NEW_SELECTION", " \"FEATTYP\" in (9732,9776) ") # Write the selected features to a new featureclass # Strip name and extension from a feature class fileName, fileExtension = os.path.splitext(LULC_lyr) LC_Agric = arcpy.CopyFeatures_management( 'LC_Agric', os.path.join(fileName + '_temp' + fileExtension)) fileName, fileExtension = os.path.splitext(TA_Multinet_lyr) TA_Airport = arcpy.CopyFeatures_management( 'TA_Airport', os.path.join(fileName + '_temp' + fileExtension)) # Make buffer around streets (10 m) fileName, fileExtension = os.path.splitext(Roads_lyr) linearDist = '10 Meters' print 'Creating buffer of ' + linearDist + ' for layer ' + Roads_lyr NAVTEQ_buff10 = arcpy.Buffer_analysis( Roads_lyr, os.path.join(fileName + '_temp' + fileExtension), linearDist, 'FULL', 'ROUND', 'ALL', '') arcpy.Delete_management(LULC_lyr, '') arcpy.Delete_management(TA_Multinet_lyr, '') arcpy.Delete_management(Roads_lyr, '') # Rename the clipped file to standard name LC_out = 'LC_Agric.shp' TA_out = 'TA_Airport.shp' NAVTQ_out = 'NAVTEQ_buff10.shp' Water_out = 'water_Broward.shp' arcpy.Rename_management(LC_Agric, 'LC_Agric.shp') arcpy.Rename_management(TA_Airport, 'TA_Airport.shp') arcpy.Rename_management(NAVTEQ_buff10, 'NAVTEQ_buff10.shp') print '\n' #UNION OF ALL SELECTED FEATURES print 'Creating Union of unsuitable habitat layers...' inFeatures = [LC_out, TA_out, NAVTQ_out, Water_out] outFeatures = 'UnsuitHab_Union' clusterTol = 0.001 UnsuitHab_Union = arcpy.Union_analysis(inFeatures, outFeatures, "ONLY_FID", clusterTol) #ERASE NON-SUITABLE HABITAT UNION FROM REFERENCE CLIPPING POLYGON FEATURE #to have a final suitable habitat vectory layer to use as polygon mask for our rasters print 'Creating suitable habitat polygon mask...' eraseOutput = 'Habitat_mask.shp' xyTol = "0.1 Meters" arcpy.Erase_analysis(Centroid_buffer_sq, UnsuitHab_Union, eraseOutput, xyTol) print '\n' #change workspace to raster folder env.workspace = 'C:\\Temp\\Raster' #simulation years (based on rasters) start_yr = 2003 end_yr = 2018 sim_yrs = range( start_yr, end_yr + 1 ) #when using range remember to add 1 to the last year to include it #Monte Carlo envelopes MC_envel = [0, 50, 100] counter = 0 #create list of labels (maybe better way to do it...but it works!) etiq = ['NA'] * len(sim_yrs) * len(MC_envel) mask_etiq = ['NA'] * len(sim_yrs) * len(MC_envel) for yr in sim_yrs: s = 'RS_' + str(yr) + '_' s_mask = 'Mask_' + str(yr) + '_' for m in MC_envel: s2 = str(m) + '.img' label = s + s2 etiq[counter] = label label_mask = s_mask + s2 mask_etiq[counter] = label_mask counter += 1 etiq = sorted(etiq) mask_etiq = sorted(mask_etiq) counter = 0 #loop through each raster in the folder for rast in arcpy.ListRasters('*'): #RESAMPLE ALL RASTERS DOWN TO 5meters (from 100m original) so that the #masking operation is more precise on the rasters # Determine the new output feature class path and name fileName, fileExtension = os.path.splitext(rast) # resampling cell size cell_size = '5' resampling_type = 'NEAREST' outRast = etiq[counter] print 'Resampling ' + rast + ' to ' + cell_size + ' meters...' arcpy.Resample_management(rast, outRast, cell_size, resampling_type) # Execute ExtractByMask inMaskData = os.path.join(newpath, 'Habitat_mask.shp') out_rast_masked = os.path.join(env.workspace, mask_etiq[counter]) print 'Extracting ' + rast + ' by mask with ' + inMaskData + ' ...' outExtractByMask = ExtractByMask(outRast, inMaskData) # Save the output outExtractByMask.save(out_rast_masked) print 'Saved mask to ' + out_rast_masked counter += 1 arcpy.Delete_management(rast, '') arcpy.Delete_management(outRast, '') #END OF LOOP! except arcpy.ExecuteError: print arcpy.GetMessages(2) arcpy.AddError(arcpy.GetMessages(2)) except Exception as e: print e.args[0] arcpy.AddError(e.args[0]) print arcpy.GetMessages()
def clip_data(input_items, out_workspace, out_coordinate_system, gcs_sr, gcs_clip_poly, out_format): """Clips input results.""" clipped = 0 errors = 0 skipped = 0 fds = None global processed_count global layer_name global existing_fields global new_fields global field_values for ds, out_name in input_items.items(): try: if not isinstance(out_name, list): out_name = '' # ----------------------------------------------- # If the item is a service layer, process and continue. # ----------------------------------------------- if ds.startswith('http'): try: if out_coordinate_system == 0: service_layer = task_utils.ServiceLayer(ds) wkid = service_layer.wkid out_sr = arcpy.SpatialReference(wkid) arcpy.env.outputCoordinateSystem = out_sr else: out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr if not out_sr.name == gcs_sr.name: try: geo_transformation = arcpy.ListTransformations(gcs_sr, out_sr)[0] clip_poly = gcs_clip_poly.projectAs(out_sr, geo_transformation) except (AttributeError, IndexError): try: clip_poly = gcs_clip_poly.projectAs(out_sr) except AttributeError: clip_poly = gcs_clip_poly except ValueError: clip_poly = gcs_clip_poly else: clip_poly = gcs_clip_poly arcpy.env.overwriteOutput = True service_layer = task_utils.ServiceLayer(ds, clip_poly.extent.JSON, 'esriGeometryEnvelope') oid_groups = service_layer.object_ids out_features = None g = 0. group_cnt = service_layer.object_ids_cnt for group in oid_groups: g += 1 group = [oid for oid in group if oid] where = '{0} IN {1}'.format(service_layer.oid_field_name, tuple(group)) url = ds + "/query?where={}&outFields={}&returnGeometry=true&f=json".format(where, '*', eval(clip_poly.JSON)) feature_set = arcpy.FeatureSet() if not out_name: out_name = service_layer.service_layer_name try: feature_set.load(url) except Exception: continue if not out_features: out_features = arcpy.Clip_analysis(feature_set, clip_poly, out_name) else: clip_features = arcpy.Clip_analysis(feature_set, clip_poly, 'in_memory/features') arcpy.Append_management(clip_features, out_features, 'NO_TEST') try: arcpy.Delete_management(clip_features) except arcpy.ExecuteError: pass status_writer.send_percent(float(g) / group_cnt, '', 'clip_data') processed_count += 1. clipped += 1 status_writer.send_percent(processed_count / result_count, _('Clipped: {0}').format(ds), 'clip_data') continue except Exception as ex: status_writer.send_state(status.STAT_WARNING, str(ex)) errors_reasons[ds] = ex.message errors += 1 continue # ----------------------------------------------- # Check if the path is a MXD data frame type. # ------------------------------------------------ map_frame_name = task_utils.get_data_frame_name(ds) if map_frame_name: ds = ds.split('|')[0].strip() # ------------------------------- # Is the input a geometry feature # ------------------------------- if isinstance(out_name, list): for row in out_name: try: arcpy.env.overwriteOutput = True name = os.path.join(out_workspace, arcpy.ValidateTableName(ds, out_workspace)) if out_format == 'SHP': name += '.shp' # Clip the geometry. geo_json = row['[geo]'] geom = arcpy.AsShape(geo_json) row.pop('[geo]') if not arcpy.Exists(name): if arcpy.env.outputCoordinateSystem: arcpy.CreateFeatureclass_management(out_workspace, os.path.basename(name), geom.type.upper()) else: arcpy.env.outputCoordinateSystem = 4326 arcpy.CreateFeatureclass_management(out_workspace, os.path.basename(name), geom.type.upper()) layer_name = arcpy.MakeFeatureLayer_management(name, 'flayer') existing_fields = [f.name for f in arcpy.ListFields(layer_name)] new_fields = [] field_values = [] for field, value in row.iteritems(): valid_field = arcpy.ValidateFieldName(field, out_workspace) new_fields.append(valid_field) field_values.append(value) try: arcpy.AddField_management(layer_name, valid_field, 'TEXT') except arcpy.ExecuteError: arcpy.DeleteField_management(layer_name, valid_field) arcpy.AddField_management(layer_name, valid_field, 'TEXT') else: if not geom.type.upper() == arcpy.Describe(name).shapeType.upper(): name = arcpy.CreateUniqueName(os.path.basename(name), out_workspace) if arcpy.env.outputCoordinateSystem: arcpy.CreateFeatureclass_management(out_workspace, os.path.basename(name), geom.type.upper()) else: arcpy.env.outputCoordinateSystem = 4326 arcpy.CreateFeatureclass_management(out_workspace, os.path.basename(name), geom.type.upper()) layer_name = arcpy.MakeFeatureLayer_management(name, 'flayer') existing_fields = [f.name for f in arcpy.ListFields(layer_name)] new_fields = [] field_values = [] for field, value in row.items(): valid_field = arcpy.ValidateFieldName(field, out_workspace) new_fields.append(valid_field) field_values.append(value) if not valid_field in existing_fields: try: arcpy.AddField_management(layer_name, valid_field, 'TEXT') except arcpy.ExecuteError: arcpy.DeleteField_management(layer_name, valid_field) arcpy.AddField_management(layer_name, valid_field, 'TEXT') clipped_geometry = arcpy.Clip_analysis(geom, gcs_clip_poly, arcpy.Geometry()) if clipped_geometry: with arcpy.da.InsertCursor(layer_name, ["SHAPE@"] + new_fields) as icur: icur.insertRow([clipped_geometry[0]] + field_values) status_writer.send_percent(processed_count / result_count, _('Clipped: {0}').format(row['name']), 'clip_data') processed_count += 1 clipped += 1 except KeyError: processed_count += 1 skipped += 1 status_writer.send_state(_(status.STAT_WARNING, 'Invalid input type: {0}').format(ds)) skipped_reasons[ds] = 'Invalid input type' except Exception as ex: processed_count += 1 errors += 1 errors_reasons[ds] = ex.message continue continue dsc = arcpy.Describe(ds) try: if dsc.spatialReference.name == 'Unknown': status_writer.send_state(status.STAT_WARNING, _('{0} has an Unknown projection. Output may be invalid or empty.').format(dsc.name)) except AttributeError: pass # -------------------------------------------------------------------- # If no output coord. system, get output spatial reference from input. # -------------------------------------------------------------------- if out_coordinate_system == 0: try: out_sr = dsc.spatialReference arcpy.env.outputCoordinateSystem = out_sr except AttributeError: out_sr = task_utils.get_spatial_reference(4326) arcpy.env.outputCoordinateSystem = out_sr else: out_sr = task_utils.get_spatial_reference(out_coordinate_system) arcpy.env.outputCoordinateSystem = out_sr # ------------------------------------------------- # If the item is not a file, project the clip area. # ------------------------------------------------- if dsc.dataType not in ('File', 'TextFile'): if not out_sr.name == gcs_sr.name: try: geo_transformation = arcpy.ListTransformations(gcs_sr, out_sr)[0] clip_poly = gcs_clip_poly.projectAs(out_sr, geo_transformation) except (AttributeError, IndexError): try: clip_poly = gcs_clip_poly.projectAs(out_sr) except AttributeError: clip_poly = gcs_clip_poly except ValueError: clip_poly = gcs_clip_poly else: clip_poly = gcs_clip_poly extent = clip_poly.extent # ----------------------------- # Check the data type and clip. # ----------------------------- # Feature Class or ShapeFile if dsc.dataType in ('FeatureClass', 'ShapeFile', 'Shapefile'): if out_name == '': name = arcpy.ValidateTableName(dsc.name, out_workspace) name = task_utils.create_unique_name(name, out_workspace) else: name = arcpy.ValidateTableName(out_name, out_workspace) name = task_utils.create_unique_name(name, out_workspace) # Does the input exist in a feature dataset? If so, create the feature dataset if it doesn't exist. ws = os.path.dirname(ds) if [any(ext) for ext in ('.gdb', '.mdb', '.sde') if ext in ws]: if os.path.splitext(ws)[1] in ('.gdb', '.mdb', '.sde'): arcpy.Clip_analysis(ds, clip_poly, name) else: fds_name = os.path.basename(ws) if not arcpy.Exists(os.path.join(out_workspace, fds_name)): arcpy.CreateFeatureDataset_management(out_workspace, fds_name, dsc.spatialReference) arcpy.Clip_analysis(ds, clip_poly, os.path.join(out_workspace, fds_name, os.path.basename(ds))) else: arcpy.Clip_analysis(ds, clip_poly, name) # Feature dataset elif dsc.dataType == 'FeatureDataset': if not out_format == 'SHP': fds_name = os.path.basename(task_utils.create_unique_name(dsc.name, out_workspace)) fds = arcpy.CreateFeatureDataset_management(out_workspace, fds_name) arcpy.env.workspace = ds for fc in arcpy.ListFeatureClasses(): try: if not out_format == 'SHP': arcpy.Clip_analysis(fc, clip_poly, task_utils.create_unique_name(fc, fds.getOutput(0))) else: arcpy.Clip_analysis(fc, clip_poly, task_utils.create_unique_name(fc, out_workspace)) except arcpy.ExecuteError: pass arcpy.env.workspace = out_workspace # Raster dataset elif dsc.dataType == 'RasterDataset': if out_name == '': name = task_utils.create_unique_name(dsc.name, out_workspace) else: name = task_utils.create_unique_name(out_name, out_workspace) ext = '{0} {1} {2} {3}'.format(extent.XMin, extent.YMin, extent.XMax, extent.YMax) arcpy.Clip_management(ds, ext, name, in_template_dataset=clip_poly, clipping_geometry="ClippingGeometry") # Layer file elif dsc.dataType == 'Layer': task_utils.clip_layer_file(dsc.catalogPath, clip_poly, arcpy.env.workspace) # Cad drawing dataset elif dsc.dataType == 'CadDrawingDataset': arcpy.env.workspace = dsc.catalogPath cad_wks_name = os.path.splitext(dsc.name)[0] for cad_fc in arcpy.ListFeatureClasses(): name = task_utils.create_unique_name('{0}_{1}'.format(cad_wks_name, cad_fc), out_workspace) arcpy.Clip_analysis(cad_fc, clip_poly, name) arcpy.env.workspace = out_workspace # File elif dsc.dataType in ('File', 'TextFile'): if dsc.catalogPath.endswith('.kml') or dsc.catalogPath.endswith('.kmz'): name = os.path.splitext(dsc.name)[0] kml_layer = arcpy.KMLToLayer_conversion(dsc.catalogPath, arcpy.env.scratchFolder, name) group_layer = arcpy.mapping.Layer(os.path.join(arcpy.env.scratchFolder, '{0}.lyr'.format(name))) for layer in arcpy.mapping.ListLayers(group_layer): if layer.isFeatureLayer: arcpy.Clip_analysis(layer, gcs_clip_poly, task_utils.create_unique_name(layer, out_workspace)) # Clean up temp KML results. arcpy.Delete_management(os.path.join(arcpy.env.scratchFolder, '{0}.lyr'.format(name))) arcpy.Delete_management(kml_layer[1]) del group_layer else: if out_name == '': out_name = dsc.name if out_workspace.endswith('.gdb'): f = arcpy.Copy_management(ds, os.path.join(os.path.dirname(out_workspace), out_name)) else: f = arcpy.Copy_management(ds, os.path.join(out_workspace, out_name)) processed_count += 1. status_writer.send_percent(processed_count / result_count, _('Copied file: {0}').format(dsc.name), 'clip_data') status_writer.send_state(_('Copied file: {0}').format(dsc.name)) clipped += 1 if out_format in ('LPK', 'MPK'): files_to_package.append(f.getOutput(0)) continue # Map document elif dsc.dataType == 'MapDocument': task_utils.clip_mxd_layers(dsc.catalogPath, clip_poly, arcpy.env.workspace, map_frame_name) else: processed_count += 1. status_writer.send_percent(processed_count / result_count, _('Invalid input type: {0}').format(ds), 'clip_data') status_writer.send_state(status.STAT_WARNING, _('Invalid input type: {0}').format(ds)) skipped += 1 skipped_reasons[ds] = _('Invalid input type: {0}').format(dsc.dataType) continue processed_count += 1. status_writer.send_percent(processed_count / result_count, _('Clipped: {0}').format(dsc.name), 'clip_data') status_writer.send_status(_('Clipped: {0}').format(dsc.name)) clipped += 1 # Continue. Process as many as possible. except Exception as ex: processed_count += 1. status_writer.send_percent(processed_count / result_count, _('Skipped: {0}').format(os.path.basename(ds)), 'clip_data') status_writer.send_status(_('FAIL: {0}').format(repr(ex))) errors_reasons[ds] = ex.message errors += 1 pass return clipped, errors, skipped
def updateParameters(self): """Modify the values and properties of parameters before internal validation is performed. This method is called whenever a parameter has been changed.""" def list_fcs(input_gdb): arcpy.env.workspace = input_gdb gdb_work = arcpy.env.workspace arcpy.Compact_management(gdb_work) datasets = arcpy.ListDatasets(feature_type='feature') datasets = [''] + datasets if datasets is not None else [] for ds in datasets: in_features = [ str(os.path.join(input_gdb, fc)) for fc in arcpy.ListFeatureClasses(feature_dataset=ds) ] return in_features if self.params[0].value is not None and self.params[4] is not None: fc_list = list_fcs(self.params[0].valueAsText) desc = arcpy.Describe(fc_list[0]).spatialReference extent = arcpy.Describe(fc_list[0]).extent sr = arcpy.SpatialReference() sr.loadFromString(self.params[4].valueAsText) to_sr = arcpy.SpatialReference(sr.factoryCode) transformations = arcpy.ListTransformations(desc, to_sr, extent) self.params[5].value = transformations[0] if self.params[1].value is not None and self.params[4] is not None: shp_list = [ os.path.join(self.params[1].valueAsText, f) for f in os.listdir(self.params[1].valueAsText) if f.endswith(".shp") ] desc = arcpy.Describe(shp_list[0]).spatialReference extent = arcpy.Describe(shp_list[0]).extent sr = arcpy.SpatialReference() sr.loadFromString(self.params[4].valueAsText) to_sr = arcpy.SpatialReference(sr.factoryCode) transformations = arcpy.ListTransformations(desc, to_sr, extent) self.params[5].value = transformations[0] if self.params[2].value is not None and self.params[4] is not None: desc = arcpy.Describe(self.params[2].value).spatialReference extent = arcpy.Describe(self.params[2].value).extent sr = arcpy.SpatialReference() sr.loadFromString(self.params[4].valueAsText) to_sr = arcpy.SpatialReference(sr.factoryCode) transformations = arcpy.ListTransformations(desc, to_sr, extent) self.params[5].value = transformations[0] if self.params[3].value is not None and self.params[4] is not None: desc = arcpy.Describe(self.params[3].valueAsText).spatialReference extent = arcpy.Describe(self.params[3].valueAsText).extent sr = arcpy.SpatialReference() sr.loadFromString(self.params[4].valueAsText) to_sr = arcpy.SpatialReference(sr.factoryCode) transformations = arcpy.ListTransformations(desc, to_sr, extent) self.params[5].value = transformations[0] return
lyr_names = sorted([str(lyr.name) for lyr in new_layers]) # Get a list of lyr names aug_track_row.append(str(tuple(lyr_names))) fc_list = [] # Add layers in new_layers to copied mdb and then create a list of the layers to then add to the map # Project the layers so that the sr's match sr = df.spatialReference print 'Adding layers to map mdb and projecting them in the maps projection' for lyr in new_layers: fc = os.path.join(workingGDB, lyr.name + '_up') # Convert to unprojected version arcpy.FeatureClassToFeatureClass_conversion(lyr, workingGDB, lyr.name + '_up') fc_sr = arcpy.Describe(fc).spatialReference geo_transformations = arcpy.ListTransformations(fc_sr, sr) fc_name = lyr.name # For getting style guide reference prj_fc = os.path.join(working_mdb_path, fc_name) # Path to projected fc if len(geo_transformations) > 0: # If there is a geo transformation required use it arcpy.Project_management(fc, prj_fc, sr, geo_transformations[0], fc_sr) fc_list.append(fc_name) continue # If no geo transformation required go ahead arcpy.Project_management(fc, prj_fc, sr) fc_list.append(fc_name) # Add the layers to the map and add to the top until new order decided
def exportDataset(xmlDoc, source, workspace, targetName, rowLimit, datasetType): result = True xmlFields = xmlDoc.getElementsByTagName("Field") dla.addMessage("Exporting Data from " + source) whereClause = "" if rowLimit != None: whereClause = getObjectIdWhereClause(source, rowLimit) if whereClause != '' and whereClause != ' ': dla.addMessage("Where " + str(whereClause)) sourceName = dla.getDatasetName(source) viewName = sourceName + "_View" dla.addMessage(viewName) targetRef = getSpatialReference(xmlDoc, "Target") sourceRef = getSpatialReference(xmlDoc, "Source") if datasetType == 'Table': isTable = True elif targetRef != '': isTable = False arcpy.env.workspace = workspace if source.lower().endswith('.lyrx') and not dla.hasJoin(source): view = dla.getLayerFromString(source) elif isTable: view = dla.makeTableView(dla.workspace, source, viewName, whereClause, xmlFields) elif not isTable: view = dla.makeFeatureView(dla.workspace, source, viewName, whereClause, xmlFields) dla.addMessage("View Created") srcCount = arcpy.GetCount_management(view).getOutput(0) dla.addMessage(str(srcCount) + " source rows") if str(srcCount) == '0': result = False dla.addError("Failed to extract " + sourceName + ", Nothing to export") else: arcpy.env.overwriteOutput = True ds = workspace + os.sep + targetName currentPreserveGlobalIDs = arcpy.env.preserveGlobalIds if dla.processGlobalIds( xmlDoc ): # both datasets have globalids in the correct workspace types arcpy.env.preserveGlobalIds = True # try to preserve dla.addMessage("Attempting to preserve GlobalIDs") else: arcpy.env.preserveGlobalIds = False # don't try to preserve dla.addMessage("Unable to preserve GlobalIDs") if isTable: arcpy.TableToTable_conversion(in_rows=view, out_path=workspace, out_name=targetName) else: spRefMatch = dla.compareSpatialRef(xmlDoc) currentRef = arcpy.env.outputCoordinateSystem # grab currrent env settings currentTrans = arcpy.env.geographicTransformations if not spRefMatch: arcpy.env.outputCoordinateSystem = targetRef transformations = arcpy.ListTransformations( sourceRef, targetRef) transformations = ";".join( transformations ) # concat the values - format change for setting the values. arcpy.env.geographicTransformations = transformations arcpy.FeatureClassToFeatureClass_conversion(in_features=view, out_path=workspace, out_name=targetName) if not spRefMatch: # set the spatial reference back arcpy.env.outputCoordinateSystem = currentRef arcpy.env.geographicTransformations = currentTrans arcpy.env.preserveGlobalIds = currentPreserveGlobalIDs removeDefaultValues( ds ) # don't want to turn nulls into defaultValues in the intermediate data # not needed if doing the transformations approach above... # if isTable: # if not createDataset('Table',workspace,targetName,None,xmlDoc,source,None): # arcpy.AddError("Unable to create intermediate table, exiting: " + workspace + os.sep + targetName) # return False # elif not isTable: # geomType = arcpy.Describe(source).shapeType # if not createDataset('FeatureClass',workspace,targetName,geomType,xmlDoc,source,targetRef): # arcpy.AddError("Unable to create intermediate feature class, exiting: " + workspace + os.sep + targetName) # return False # fieldMap = getFieldMap(view,ds) # arcpy.Append_management(view,ds,schema_type="NO_TEST",field_mapping=fieldMap) dla.addMessage(arcpy.GetMessages(2)) # only serious errors count = arcpy.GetCount_management(ds).getOutput(0) dla.addMessage(str(count) + " source rows exported to " + targetName) if str(count) == '0': result = False dla.addError( "Failed to load to " + targetName + ", it is likely that your data falls outside of the target Spatial Reference Extent or there is another basic issue" ) dla.addError( "To verify please use the Append and/or Copy Features tool to load some data to an intermediate dataset:" ) dla.addError(ds) dla.showTraceback() return result
def project_as(input_dataframe: pd.DataFrame, output_spatial_reference: [int, SpatialReference] = 4326, input_spatial_reference: [int, SpatialReference] = None, transformation_name: str = None) -> pd.DataFrame: """ Project input Spatially Enabled Dataframe to a desired output spatial reference, applying a transformation if needed due to the geographic coordinate system changing. Args: input_dataframe: Valid Spatially Enabled DataFrame output_spatial_reference: Optional - Desired output Spatial Reference. Default is 4326 (WGS84). input_spatial_reference: Optional - Only necessary if the Spatial Reference is not properly defined for the input data geometry. transformation_name: Optional - Transformation name to be used, if needed, to convert between spatial references. If not explicitly provided, this will be inferred based on the spatial reference of the input data and desired output spatial reference. Returns: Spatially Enabled DataFrame in the desired output spatial reference. """ # ensure the geometry is set geom_col_lst = [c for c in input_dataframe.columns if input_dataframe[c].dtype.name.lower() == 'geometry'] assert len(geom_col_lst) > 0, 'The DataFrame does not appear to have a geometry column defined. This can be ' \ 'accomplished using the "input_dataframe.spatial.set_geometry" method.' # save the geometry column to a variable geom_col = geom_col_lst[0] # ensure the input spatially enabled dataframe validates assert input_dataframe.spatial.validate(), 'The DataFrame does not appear to be valid.' # if a spatial reference is set for the dataframe, just use it if input_dataframe.spatial.sr is not None: in_sr = input_dataframe.spatial.sr # if a spatial reference is explicitly provided, but the data does not have one set, use the one provided elif input_spatial_reference is not None: # check the input assert isinstance(input_spatial_reference, int) or isinstance(input_spatial_reference, SpatialReference), \ f'input_spatial_reference must be either an int referencing a wkid or a SpatialReference object, ' \ f'not {type(input_spatial_reference)}.' if isinstance(input_spatial_reference, int): in_sr = SpatialReference(input_spatial_reference) else: in_sr = input_spatial_reference # if the spatial reference is not set, common for data coming from geojson, check if values are in lat/lon # range, and if so, go with WGS84, as this is likely the case if in this range else: # get the bounding values for the data x_min, y_min, x_max, y_max = input_dataframe.spatial.full_extent # check the range of the values, if in longitude and latitude range wgs_range = True if (x_min > -181 and y_min > -91 and x_max < 181 and y_max < 91) else False assert wgs_range, 'Input data for projection data must have a spatial reference, or one must be provided.' # if the values are in range, run with it in_sr = SpatialReference(4326) # ensure the output spatial reference is a SpatialReference object instance if isinstance(output_spatial_reference, SpatialReference): out_sr = output_spatial_reference else: out_sr = SpatialReference(output_spatial_reference) # copy the input spatially enabled dataframe since the project function changes the dataframe in place out_df = input_dataframe.copy() out_df.spatial.set_geometry(geom_col) # if arcpy is available, use it to find the transformation if arcpy_avail and transformation_name is None: # get any necessary transformations using arcpy, which returns only a list of transformation names trns_lst = arcpy.ListTransformations(in_sr.as_arcpy, out_sr.as_arcpy) # otherwise we will have to use the geometry rest endpoint to find transformations elif transformation_name is None: # explicitly ensure find_transformations has a gis instance gis = active_gis if active_gis else GIS() # get any transformations, if needed due to changing geographic spatial reference, as a list of dicts trns_lst = find_transformation(in_sr, out_sr, gis=gis)['transformations'] # apply across the geometries using apply since it recognizes the transformation correctly if transformation # is necessary and also tries arcpy first, and if not available, rolls back to rest resources elegantly if len(trns_lst) or transformation_name is not None: trns = transformation_name if transformation_name is not None else trns_lst[0] out_df[geom_col] = out_df[geom_col].apply(lambda geom: geom.project_as(out_sr, trns)) # otherwise, do the same thing using the apply method since the geoaccessor project method is not working reliably # and only if necessary if the spatial reference is being changed elif in_sr.wkid != out_sr.wkid: out_df[geom_col] = out_df[geom_col].apply(lambda geom: geom.project_as(out_sr)) # ensure the spatial column is set if not len([c for c in out_df.columns if out_df[c].dtype.name.lower() == 'geometry']): out_df.spatial.set_geometry(geom_col) return out_df
def copy_teilflaechen_to_gdb(self, project_name, flaeche): """add layer teilflächen to gdb""" arcpy.SetProgressorLabel('Teilflächen laden') arcpy.SetProgressorPosition(30) tfl = self.folders.get_table('Teilflaechen_Plangebiet', project=project_name, check=False) if arcpy.Exists(tfl): arcpy.Delete_management(tfl) # epsg-code or the config = self.parent_tbx.config sr1 = arcpy.Describe(flaeche).spatialReference if not sr1.factoryCode: raise Exception(u'Den Teilflächen fehlen Angaben zur Projektion. ' u'Bitte definieren Sie die Projektion in der Quelle!') sr2 = arcpy.SpatialReference(config.epsg) possible_transformations = arcpy.ListTransformations(sr1, sr2) if not possible_transformations: temp_path = self.folders.get_temporary_projectpath() temp_shapefile = os.path.join(temp_path, 'tempfile.shp') sr0 = arcpy.SpatialReference(4326) possible_transformations = arcpy.ListTransformations(sr1, sr0) transform_method = possible_transformations[0] arcpy.Project_management(flaeche, temp_shapefile, sr0, transform_method) possible_transformations = arcpy.ListTransformations(sr0, sr2) transform_method = possible_transformations[0] arcpy.Project_management(temp_shapefile, tfl, sr2, transform_method) arcpy.Delete_management(temp_shapefile) else: transform_method = possible_transformations[0] arcpy.Project_management(flaeche, tfl, sr2, transform_method) gdbPfad = self.folders.get_db() arcpy.env.workspace = gdbPfad # Prepare Shapefile for use in RPC # delete unused fields fieldObjList = arcpy.ListFields(tfl) fieldNameList = [] for field in fieldObjList: if not field.required: fieldNameList.append(field.name) if fieldNameList: arcpy.DeleteField_management(tfl, fieldNameList) # add needed fields arcpy.AddField_management(tfl, "id_teilflaeche", "LONG") arcpy.AddField_management(tfl, "Name", "TEXT") arcpy.AddField_management(tfl, "Beginn_Nutzung", "LONG") arcpy.AddField_management(tfl, "Aufsiedlungsdauer", "LONG") arcpy.AddField_management(tfl, "Flaeche_ha", "DOUBLE") arcpy.AddField_management(tfl, "umfang_meter", "FLOAT") arcpy.AddField_management(tfl, "Nutzungsart", "SHORT") arcpy.AddField_management(tfl, "ags_bkg", "TEXT") arcpy.AddField_management(tfl, "gemeinde_name", "TEXT") arcpy.AddField_management(tfl, "validiert", "SHORT") arcpy.AddField_management(tfl, "WE_gesamt", "LONG") arcpy.AddField_management(tfl, "AP_gesamt", "LONG") arcpy.AddField_management(tfl, "VF_gesamt", "LONG") arcpy.AddField_management(tfl, "ew", "LONG") arcpy.AddField_management(tfl, "Wege_gesamt", "LONG") arcpy.AddField_management(tfl, "Wege_MIV", "LONG") #arcpy.AddField_management(teilfaechen_plangebiet, "Bilanzsumme", "FLOAT") return tfl, gdbPfad
def delinFlowDistBuff(in_Feats, fld_ID, in_FlowDir, out_Feats, maxDist, dilDist = 0, out_Scratch = 'in_memory'): '''Delineates buffers based on flow distance down to features (rather than straight distance)''' # Get cell size and output spatial reference from in_FlowDir cellSize = (arcpy.GetRasterProperties_management(in_FlowDir, "CELLSIZEX")).getOutput(0) srRast = arcpy.Describe(in_FlowDir).spatialReference linUnit = srRast.linearUnitName printMsg('Cell size of flow direction raster is %s %ss' %(cellSize, linUnit)) printMsg('Flow modeling is strongly dependent on cell size.') # Set environment setting and other variables arcpy.env.overwriteOutput = True arcpy.env.snapRaster = in_FlowDir procDist = 2*maxDist # dist = float(cellSize) # dilDist = "%s %ss" % (str(dist), linUnit) # decided to make this a user input # Check if input features and input flow direction have same spatial reference. # If so, just make a copy. If not, reproject features to match raster. srFeats = arcpy.Describe(in_Feats).spatialReference if srFeats.Name == srRast.Name: printMsg('Coordinate systems for features and raster are the same. Copying...') arcpy.CopyFeatures_management (in_Feats, out_Feats) else: printMsg('Reprojecting features to match raster...') # Check if geographic transformation is needed, and handle accordingly. if srFeats.GCS.Name == srRast.GCS.Name: geoTrans = "" printMsg('No geographic transformation needed...') else: transList = arcpy.ListTransformations(srFeats,srRast) geoTrans = transList[0] arcpy.Project_management (in_Feats, out_Feats, srRast, geoTrans) # Count features and report numFeats = countFeatures(out_Feats) printMsg('There are %s features to process.' % numFeats) # Create an empty list to store IDs of features that fail to get processed myFailList = [] # Set up processing cursor and loop flags = [] # Initialize empty list to keep track of suspects cursor = arcpy.da.UpdateCursor(out_Feats, [fld_ID, "SHAPE@"]) counter = 1 for row in cursor: trashList = [] # Empty list for trash collection try: # Extract the unique ID and geometry object myID = row[0] myShape = row[1] printMsg('Working on feature %s with ID %s' % (counter, str(myID))) # Process: Select (Analysis) # Create a temporary feature class including only the current feature selQry = "%s = %s" % (fld_ID, str(myID)) tmpFeat = out_Scratch + os.sep + 'tmpFeat' trashList.append(tmpFeat) arcpy.Select_analysis (out_Feats, tmpFeat, selQry) # Convert feature to raster printMsg('Converting feature to raster...') srcRast = out_Scratch + os.sep + 'srcRast' trashList.append(srcRast) arcpy.PolygonToRaster_conversion (tmpFeat, fld_ID, srcRast, "MAXIMUM_COMBINED_AREA", fld_ID, cellSize) # Clip flow direction raster to processing buffer procBuff = out_Scratch + os.sep + 'procBuff' trashList.append(procBuff) printMsg('Buffering feature to set maximum processing distance') arcpy.Buffer_analysis (tmpFeat, procBuff, procDist, "", "", "ALL", "") myExtent = str(arcpy.Describe(procBuff).extent).replace(" NaN", "") printMsg('Extent: %s' %myExtent) clp_FlowDir = out_Scratch + os.sep + 'clp_FlowDir' trashList.append(clp_FlowDir) printMsg('Clipping flow direction raster to processing buffer') arcpy.Clip_management (in_FlowDir, myExtent, clp_FlowDir, procBuff, "", "ClippingGeometry") arcpy.env.extent = clp_FlowDir # Burn SCU feature into flow direction raster as sink printMsg('Creating sink from feature...') snk_FlowDir = Con(IsNull(srcRast),clp_FlowDir) trashList.append(snk_FlowDir) snk_FlowDir.save(out_Scratch + os.sep + 'snk_FlowDir') # Calculate flow distance down to sink printMsg('Calculating flow distance to feature...') FlowDist = FlowLength (snk_FlowDir, "DOWNSTREAM") FlowDist.save(out_Scratch + os.sep + 'FlowDist') trashList.append(FlowDist) # Clip flow distance raster to the maximum distance buffer clipBuff = out_Scratch + os.sep + 'clipBuff' trashList.append(clipBuff) arcpy.Buffer_analysis (tmpFeat, clipBuff, maxDist, "", "", "ALL", "") myExtent = str(arcpy.Describe(clipBuff).extent).replace(" NaN", "") #printMsg('Extent: %s' %myExtent) clp_FlowDist = out_Scratch + os.sep + 'clp_FlowDist' trashList.append(clp_FlowDist) printMsg('Clipping flow distance raster to maximum distance buffer') arcpy.Clip_management (FlowDist, myExtent, clp_FlowDist, clipBuff, "", "ClippingGeometry") arcpy.env.extent = clp_FlowDist # Make a binary raster based on flow distance printMsg('Creating binary raster from flow distance...') binRast = Con((IsNull(clp_FlowDist) == 1), (Con((IsNull(srcRast)== 0),1,0)), (Con((Raster(clp_FlowDist) <= maxDist),1,0))) binRast.save(out_Scratch + os.sep + 'binRast') trashList.append(binRast) printMsg('Boundary cleaning...') cleanRast = BoundaryClean (binRast, 'NO_SORT', 'TWO_WAY') cleanRast.save(out_Scratch + os.sep + 'cleanRast') trashList.append(cleanRast) printMsg('Setting zeros to nulls...') prePoly = SetNull (cleanRast, 1, 'Value = 0') prePoly.save(out_Scratch + os.sep + 'prePoly') trashList.append(prePoly) # Convert raster to polygon printMsg('Converting flow distance raster to polygon...') finPoly = out_Scratch + os.sep + 'finPoly' trashList.append(finPoly) arcpy.RasterToPolygon_conversion (prePoly, finPoly, "NO_SIMPLIFY") # If user specifies, coalesce to smooth if dilDist == 0: printMsg('Final shape will not be smoothed.') coalPoly = finPoly else: printMsg('Smoothing final shape...') coalPoly = out_Scratch + os.sep + 'coalPoly' Coalesce(finPoly, dilDist, coalPoly, 'in_memory') trashList.append(coalPoly) # Check the number of features at this point. # It should be just one. If more, the output is likely bad and should be flagged. count = countFeatures(coalPoly) if count > 1: printWrng('Output is suspect for feature %s' % str(myID)) flags.append(myID) # Dissolve to create a multipart feature so at least we can finish the job. multiPoly = out_Scratch + os.sep + 'multiPoly' arcpy.Dissolve_management (coalPoly, multiPoly, "", "", "MULTI_PART") coalPoly = multiPoly # Use the flow distance buffer geometry as the final shape myFinalShape = arcpy.SearchCursor(coalPoly).next().Shape # Update the feature with its final shape row[1] = myFinalShape cursor.updateRow(row) del row printMsg('Finished processing feature %s' %str(myID)) # Reset extent, because Arc is stupid. arcpy.env.extent = "MAXOF" # Throw out trash after every cycle and compact the scratch GDB periodically. # Grasping at straws here to avoid failure processing large datasets. garbagePickup(trashList) for item in trashList: del item if counter%25 == 0: printMsg('Compacting scratch geodatabase...') arcpy.Compact_management (out_Scratch) # Update counter counter += 1 except: # Add failure message and append failed feature ID to list printMsg("\nFailed to fully process feature " + str(myID)) myFailList.append(myID) # Error handling code swiped from "A Python Primer for ArcGIS" tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + str(sys.exc_info()[1]) msgs = "ARCPY ERRORS:\n" + arcpy.GetMessages(2) + "\n" printWrng(msgs) printWrng(pymsg) printMsg(arcpy.GetMessages(1)) # Add status message printMsg("\nMoving on to the next feature. Note that the output will be incomplete.") if len(flags) > 0: printWrng('These features may be incorrect: %s' % str(flags)) if len(myFailList) > 0: printWrng('These features failed to process: %s' % str(myFailList)) return out_Feats
def getZonalStats(in_Polys, in_Raster, fld_ID, fld_Stats, type_Stats, out_Polys, out_Scratch = 'in_memory'): '''Attaches zonal statistics from a raster to polygons''' # Environment settings arcpy.env.overwriteOutput = True cellSize = (arcpy.GetRasterProperties_management(in_Raster, "CELLSIZEX")).getOutput(0) arcpy.env.cellSize = cellSize printMsg('Cell Size is %s map units' % str(cellSize)) arcpy.env.snapRaster = in_Raster # Check if input polygons and raster have same spatial reference. # If so, all good. If not, reproject features to match raster. srPolys = arcpy.Describe(in_Polys).spatialReference srRast = arcpy.Describe(in_Raster).spatialReference if srPolys.Name == srRast.Name: printMsg('Coordinate systems for features and raster are the same. Copying...') arcpy.CopyFeatures_management (in_Polys, out_Polys) else: printMsg('Reprojecting features to match raster...') # Check if geographic transformation is needed, and handle accordingly. if srPolys.GCS.Name == srRast.GCS.Name: geoTrans = "" printMsg('No geographic transformation needed...') else: transList = arcpy.ListTransformations(srPolys,srRast) geoTrans = transList[0] arcpy.Project_management (in_Polys, out_Polys, srRast, geoTrans) # Set up some variables used in loop below tmpFeat = out_Scratch + os.sep + 'tmpFeat' # temp feature class tmpTab = out_Scratch + os.sep + 'tmpTab' # temp table mstrTab = out_Scratch + os.sep + 'mstrTab' # master table for t in [tmpTab, mstrTab]: if arcpy.Exists(t): arcpy.Delete_management(t) myFailList = [] # empty list to keep track of failures # Count features and report numFeats = countFeatures(out_Polys) printMsg('There are %s features to process.' % numFeats) # Set up processing cursor and loop through polygons to get zonal stats. # This is done in a loop instead of all at once to avoid problems if polys overlap. cursor = arcpy.da.SearchCursor(out_Polys, '%s' % fld_ID) counter = 1 for row in cursor: try: myID = row[0] printMsg('Working on zonal stats for feature %s with ID %s' % (counter, str(myID))) # Make temporary feature class selQry = "%s = %s" % (fld_ID, str(myID)) arcpy.Select_analysis (out_Polys, tmpFeat, selQry) # Run zonal stats and append to master table outTab = ZonalStatisticsAsTable (tmpFeat, fld_ID, in_Raster, tmpTab, 'DATA', 'ALL') if arcpy.Exists(mstrTab): arcpy.Append_management(tmpTab, mstrTab, 'NO_TEST') else: arcpy.Copy_management(tmpTab, mstrTab) # Updates del row, outTab counter += 1 # Reset extent, because Arc is stupid. arcpy.env.extent = "MAXOF" except: # Add failure message and append failed feature ID to list printMsg("\nFailed to fully process feature " + str(myID)) myFailList.append(myID) # Error handling code swiped from "A Python Primer for ArcGIS" tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + str(sys.exc_info()[1]) msgs = "ARCPY ERRORS:\n" + arcpy.GetMessages(2) + "\n" printWrng(msgs) printWrng(pymsg) printMsg(arcpy.GetMessages(1)) # Add status message printMsg("\nMoving on to the next feature. Note that the output will be incomplete.") del cursor # For each stats type, manipulate the fields printMsg('Appending stats fields to output features') polyFldNames = [field.name for field in arcpy.ListFields(out_Polys)] printMsg(polyFldNames) for t in type_Stats: fldName = fld_Stats + '_' + t if fldName in polyFldNames: arcpy.DeleteField_management(out_Polys, fldName) arcpy.AddField_management (mstrTab, fldName, 'FLOAT') expression = '!%s!' % t try: arcpy.CalculateField_management(mstrTab, fldName, expression, 'PYTHON') arcpy.JoinField_management(out_Polys, fld_ID, mstrTab, fld_ID, fldName) # I put this in a try block b/c certain stats, such as MEDIAN, are apparently only available for integer rasters. except: printWrng('Unable to add %s' %t) # Error handling code swiped from "A Python Primer for ArcGIS" tb = sys.exc_info()[2] tbinfo = traceback.format_tb(tb)[0] pymsg = "PYTHON ERRORS:\nTraceback Info:\n" + tbinfo + "\nError Info:\n " + str(sys.exc_info()[1]) msgs = "ARCPY ERRORS:\n" + arcpy.GetMessages(2) + "\n" printWrng(msgs) printWrng(pymsg) printMsg(arcpy.GetMessages(1)) return out_Polys
arcpy.ASCIIToRaster_conversion(full_path, out_ras) print("%s raster created in Climate_Variables.gdb"%(out_ras)) print("Defining the projection for %s as:\n %s"%(out_ras, coor_sys)) arcpy.DefineProjection_management(out_ras, coor_sys) print("Projection successfully defined! \n") #NAD_1983_HARN_StatePlane_ Washington_South_FIPS_4602 outworkspace = "F:/GIS_Projects/420/Quarterman_ENVS420_Lab5/Climate_Variables/Climate_Variables_2080_projected_BL.gdb" from_sr = arcpy.Describe(out_ras).spatialReference outfc = os.path.join(outworkspace, out_ras) outCS = arcpy.SpatialReference("F:/GIS_Projects/420/Quarterman_ENVS420_Lab5/Sitka_Spruce_Correct_Projection/Sitka_Spruce_Range.prj") print("Input spatial reference for %s is:\n %s"%(out_ras, from_sr)) exte = arcpy.Describe(out_ras).extent print("Spatial extent of impot:") print(exte) trans_list = arcpy.ListTransformations(from_sr, outCS, exte) print("List of transformations here:") print(trans_list) trans = trans_list[0] print("Projecting: %s to match the defined projection of Sitka_Spruce_Range" %(out_ras)) arcpy.ProjectRaster_management(out_ras, outfc, outCS, "BILINEAR", "1000", trans, "#", "#") print(out_ras + ' Projected!') except: