def RotateFeatureClass(inputFC, outputFC, angle=0, pivot_type="CENTER", pivot_point=None): """Rotate Feature Class inputFC Input features outputFC Output feature class angle Angle to rotate, in degrees pivot_type CENTER, LOWER_LEFT, LOWER_RIGHT, UPPER_LEFT, UPPER_RIGHT, XY pivot_point X,Y coordinates (as space-separated string) (only used if pivot_type = "XY") """ # temp names for cleanup env_file, lyrTmp, tmpFC = [None] * 3 Row, Rows, oRow, oRows = [None] * 4 # cursors # warning thresholds for complex features warnPts = 10000 warnPrt = 10 try: # process parameters try: angle = float(angle) except: raise MsgError("Invalid value for rotation: {0}".format(angle)) # determine pivot point ext = arcpy.Describe(inputFC).extent if pivot_type == "CENTER": pivot_point = (ext.XMin + ext.width * 0.5, ext.YMin + ext.height * 0.5) elif pivot_type == "LOWER_LEFT": pivot_point = ext.XMin, ext.YMin elif pivot_type == "UPPER_LEFT": pivot_point = ext.XMin, ext.YMax elif pivot_type == "UPPER_RIGHT": pivot_point = ext.XMax, ext.YMax elif pivot_type == "LOWER_RIGHT": pivot_point = ext.XMax, ext.YMin elif pivot_type == "XY": try: pivot_point = tuple([float(xy) for xy in pivot_point.split()]) except: raise Exception("Invalid value for pivot point: %s" % pivot_point) xcen, ycen = pivot_point # msg = "Rotating {0} degrees around {1} ({2:.1f}, {3:.1f})" # GPMsg(msg.format(angle, pivot_type, xcen, ycen)) # set up environment env_file = arcpy.CreateScratchName("xxenv", ".xml", "file", arcpy.GetSystemEnvironment("TEMP")) arcpy.SaveSettings(env_file) # Disable any GP environment clips or project on the fly arcpy.ClearEnvironment("extent") arcpy.ClearEnvironment("outputCoordinateSystem") WKS = env.workspace if not WKS: if os.path.dirname(outputFC): WKS = os.path.dirname(outputFC) else: WKS = os.path.dirname(arcpy.Describe(inputFC).catalogPath) env.workspace = env.scratchWorkspace = WKS # get feature class properties dFC = arcpy.Describe(inputFC) shpField = dFC.shapeFieldName shpType = dFC.shapeType FID = dFC.OIDFieldName SR = dFC.spatialReference # create temp feature class tmpFC = arcpy.CreateScratchName("xxfc", "", "featureclass") arcpy.CreateFeatureclass_management(os.path.dirname(tmpFC), os.path.basename(tmpFC), shpType, spatial_reference=SR) # set up id field (used to join later) TFID = "ORIG_FID" arcpy.AddField_management(tmpFC, TFID, "LONG") arcpy.DeleteField_management(tmpFC, "ID") # rotate the feature class coordinates # only points, polylines, and polygons are supported ##GPMsg("t", "writing") # open read and write cursors Rows = arcpy.SearchCursor(inputFC, "", "", "%s;%s" % (shpField, FID)) oRows = arcpy.InsertCursor(tmpFC) if shpType == "Point": for Row in Rows: shp = Row.getValue(shpField) pnt = shp.getPart() pnt.X, pnt.Y = RotateXY(pnt.X, pnt.Y, xcen, ycen, angle) oRow = oRows.newRow() oRow.setValue(shpField, pnt) oRow.setValue(TFID, Row.getValue(FID)) oRows.insertRow(oRow) elif shpType in ["Polyline", "Polygon"]: # initialize total area / length totarea_in, totarea_out = 0.0, 0.0 parts = arcpy.Array() rings = arcpy.Array() ring = arcpy.Array() for Row in Rows: shp = Row.getValue(shpField) if shpType == "Polygon": totarea_in += shp.area p = 0 for part in shp: for pnt in part: if pnt: x, y = RotateXY(pnt.X, pnt.Y, xcen, ycen, angle) ring.add(arcpy.Point(x, y, pnt.ID)) else: # if we have a ring, save it if len(ring) > 0: rings.add(ring) ring.removeAll() # we have our last ring, add it rings.add(ring) ring.removeAll() # if only one, remove nesting if len(rings) == 1: rings = rings.getObject(0) parts.add(rings) rings.removeAll() p += 1 # if only one, remove nesting if len(parts) == 1: parts = parts.getObject(0) if dFC.shapeType == "Polyline": shp = arcpy.Polyline(parts) else: shp = arcpy.Polygon(parts) totarea_out += shp.area if shp.pointCount > warnPts or shp.partCount > warnPrt: GPMsg("w", ("Feature {0} contains {1} points, " "{2} parts").format(Row.getValue(FID), shp.pointCount, shp.partCount)) parts.removeAll() oRow = oRows.newRow() oRow.setValue(shpField, shp) oRow.setValue(TFID, Row.getValue(FID)) oRows.insertRow(oRow) else: raise Exception, "Shape type {0} is not supported".format(shpType) del Row, Rows, oRow, oRows # close write cursor (ensure buffer written) Row, Rows, oRow, oRows = [None] * 4 # restore variables for cleanup if shpType == "Polygon": # check - did the area change more than 0.1 percent? diff = totarea_out - totarea_in diffpct = 100.0 * diff / totarea_in if abs(diffpct) > 1.0: GPMsg("w", "Please check output polygons") GPMsg( "w", "Input area: {0:.1f} Output area: {1:.1f}".format( totarea_in, totarea_out)) GPMsg("w", "({:.1f} percent change)".format(diffpct)) # join attributes, and copy to output lyrTmp = "lyrTmp" arcpy.MakeFeatureLayer_management(tmpFC, lyrTmp) arcpy.AddJoin_management(lyrTmp, TFID, inputFC, FID) env.qualifiedFieldNames = False arcpy.CopyFeatures_management(lyrTmp, outputFC) env.qualifiedFieldNames = True # Fourth field [3] is a duplicate of TFID dropField = arcpy.ListFields(outputFC)[3].name arcpy.DeleteField_management(outputFC, dropField) except MsgError, xmsg: GPMsg("e", str(xmsg))
def RotateFeatureClass(inputFC, outputFC, angle=0, pivot_point=None): """Rotate Feature Class inputFC Input features outputFC Output feature class angle Angle to rotate, in degrees pivot_point X,Y coordinates (as space-separated string) Default is lower-left of inputFC As the output feature class no longer has a "real" xy locations, after rotation, it no coordinate system defined. """ def RotateXY(x, y, xc=0, yc=0, angle=0, units="DEGREES"): """Rotate an xy cooordinate about a specified origin x,y xy coordinates xc,yc center of rotation angle angle units "DEGREES" (default) or "RADIANS" """ import math x = x - xc y = y - yc # make angle clockwise (like Rotate_management) angle = angle * -1 if units == "DEGREES": angle = math.radians(angle) xr = (x * math.cos(angle)) - (y * math.sin(angle)) + xc yr = (x * math.sin(angle)) + (y * math.cos(angle)) + yc return xr, yr # temp names for cleanup env_file = None lyrFC, lyrTmp, lyrOut = [None] * 3 # layers tmpFC = None # temp dataset Row, Rows, oRow, oRows = [None] * 4 # cursors try: # process parameters try: xcen, ycen = [float(xy) for xy in pivot_point.split()] pivot_point = xcen, ycen except: # if pivot point was not specified, get it from # the lower-left corner of the feature class ext = arcpy.Describe(inputFC).extent xcen, ycen = ext.XMin, ext.YMin pivot_point = xcen, ycen angle = float(angle) # set up environment env_file = arcpy.CreateScratchName("xxenv",".xml","file", os.environ["TEMP"]) arcpy.SaveSettings(env_file) # Disable any GP environment clips or project on the fly arcpy.ClearEnvironment("extent") arcpy.ClearEnvironment("outputCoordinateSystem") WKS = env.workspace if not WKS: if os.path.dirname(outputFC): WKS = os.path.dirname(outputFC) else: WKS = os.path.dirname( arcpy.Describe(inputFC).catalogPath) env.workspace = env.scratchWorkspace = WKS # Disable GP environment clips or project on the fly arcpy.ClearEnvironment("extent") arcpy.ClearEnvironment("outputCoordinateSystem") # get feature class properties lyrFC = "lyrFC" arcpy.MakeFeatureLayer_management(inputFC, lyrFC) dFC = arcpy.Describe(lyrFC) shpField = dFC.shapeFieldName shpType = dFC.shapeType FID = dFC.OIDFieldName # create temp feature class tmpFC = arcpy.CreateScratchName("xxfc","","featureclass") arcpy.CreateFeatureclass_management(os.path.dirname(tmpFC), os.path.basename(tmpFC), shpType) lyrTmp = "lyrTmp" arcpy.MakeFeatureLayer_management(tmpFC, lyrTmp) # set up id field (used to join later) TFID = "XXXX_FID" arcpy.AddField_management(lyrTmp, TFID, "LONG") arcpy.DeleteField_management(lyrTmp, "ID") # rotate the feature class coordinates # only points, polylines, and polygons are supported # open read and write cursors Rows = arcpy.SearchCursor(lyrFC, "", "", "%s;%s" % (shpField,FID)) oRows = arcpy.InsertCursor(lyrTmp) if shpType == "Point": for Row in Rows: shp = Row.getValue(shpField) pnt = shp.getPart() pnt.X, pnt.Y = RotateXY(pnt.X,pnt.Y,xcen,ycen,angle) oRow = oRows.newRow() oRow.setValue(shpField, pnt) oRow.setValue(TFID,Row.getValue(FID)) oRows.insertRow(oRow) elif shpType in ["Polyline","Polygon"]: parts = arcpy.Array() rings = arcpy.Array() ring = arcpy.Array() for Row in Rows: shp = Row.getValue(shpField) p = 0 for part in shp: for pnt in part: if pnt: x, y = RotateXY(pnt.X, pnt.Y, xcen, ycen, angle) ring.add(arcpy.Point(x, y, pnt.ID)) else: # if we have a ring, save it if len(ring) > 0: rings.add(ring) ring.removeAll() # we have our last ring, add it rings.add(ring) ring.removeAll() # if only one, remove nesting if len(rings) == 1: rings = rings.getObject(0) parts.add(rings) rings.removeAll() p += 1 # if only one, remove nesting if len(parts) == 1: parts = parts.getObject(0) if dFC.shapeType == "Polyline": shp = arcpy.Polyline(parts) else: shp = arcpy.Polygon(parts) parts.removeAll() oRow = oRows.newRow() oRow.setValue(shpField, shp) oRow.setValue(TFID,Row.getValue(FID)) oRows.insertRow(oRow) else: #raise Exception, "Shape type {0} is not supported".format(shpType) #UPDATE raise Exception("Shape type {0} is not supported".format(shpType)) del oRow, oRows # close write cursor (ensure buffer written) oRow, oRows = None, None # restore variables for cleanup # join attributes, and copy to output arcpy.AddJoin_management(lyrTmp, TFID, lyrFC, FID) env.qualifiedFieldNames = False arcpy.Merge_management(lyrTmp, outputFC) lyrOut = "lyrOut" arcpy.MakeFeatureLayer_management(outputFC, lyrOut) # drop temp fields 2,3 (TFID, FID) fnames = [f.name for f in arcpy.ListFields(lyrOut)] dropList = ";".join(fnames[2:4]) arcpy.DeleteField_management(lyrOut, dropList) #except MsgError, xmsg: #UPDATE except MsgError as xmsg: arcpy.AddError(str(xmsg)) except arcpy.ExecuteError: tbinfo = traceback.format_tb(sys.exc_info()[2])[0] arcpy.AddError(tbinfo.strip()) arcpy.AddError(arcpy.GetMessages()) numMsg = arcpy.GetMessageCount() for i in range(0, numMsg): arcpy.AddReturnMessage(i) #except Exception, xmsg: #UPDATE except Exception as xmsg: tbinfo = traceback.format_tb(sys.exc_info()[2])[0] arcpy.AddError(tbinfo + str(xmsg)) finally: # reset environment if env_file: arcpy.LoadSettings(env_file) # Clean up temp files for f in [lyrFC, lyrTmp, lyrOut, tmpFC, env_file]: try: if f: arcpy.Delete_management(f) except: pass # delete cursors try: for c in [Row, Rows, oRow, oRows]: del c except: pass # return pivot point try: pivot_point = "{0} {1}".format(*pivot_point) except: pivot_point = None return pivot_point
# -*- coding: cp936 -*- import arcpy, os # 获取到的结果可能为空 print arcpy.GetSystemEnvironment("TEMP") print arcpy.GetSystemEnvironment("TMP") print arcpy.GetSystemEnvironment("MW_TMPDIR") # 获取默认的overwriteOutput环境值,并将overwriteOutput设为True print arcpy.env.overwriteOutput arcpy.env.overwriteOutput = True print arcpy.env.overwriteOutput # 保存当前环境设置,并将overwriteOutput设为False arcpy.SaveSettings(os.path.join(os.path.expanduser("~"), "Desktop", "MyCustomSettings.xml")) arcpy.env.overwriteOutput = False print arcpy.env.overwriteOutput # 重新读取导出的环境设置文件 arcpy.LoadSettings(os.path.join(os.path.expanduser("~"), "Desktop", "MyCustomSettings.xml")) print arcpy.env.overwriteOutput