I am wanting to take a symbolized layer in an mxd, and save it's symbol color (like a polygon fill) into its attribute table as an RGB value. My goal is to use this value in MapInfo to symbolize it's features via Discover.
I can't see any obvious way of using the ArcPy mapping module to read the particular values. Has anyone had a hack at building a simple modern solution?
-
How's your .net? Access to the IColor from the UniqueValuesRenderer is available from .net (vb.net, c#). There are ways of wrapping these objects for python but that's way advanced python!Michael Stimson– Michael Stimson2014年12月04日 04:53:24 +00:00Commented Dec 4, 2014 at 4:53
-
My .net is dodgy. But it is food for thought. Thank you for the key words, I will look into it.GISI– GISI2014年12月04日 05:34:58 +00:00Commented Dec 4, 2014 at 5:34
-
If you've got a VBA license it might be easier. Should this be the case I could put a little bit of code together.Michael Stimson– Michael Stimson2014年12月04日 05:35:58 +00:00Commented Dec 4, 2014 at 5:35
-
Alas, no we don't have a licence. But, it was very kind of you to offer. Thank you.GISI– GISI2014年12月04日 05:43:40 +00:00Commented Dec 4, 2014 at 5:43
-
This is a good question but I think it is a duplicate of gis.stackexchange.com/questions/71352/… and that you appear to be asking it to meet requirements similar to these gis.stackexchange.com/questions/27807/…PolyGeo– PolyGeo ♦2014年12月04日 05:50:45 +00:00Commented Dec 4, 2014 at 5:50
1 Answer 1
I only need to get RGB values for polygon features. In particular solid fill vegetation and geology. I made a rough as guts ArcPy tool that fits my purpose.
The tool gets the user to nominate their layer and symbology field in ArcMap. The tool then loops through groups of "like sybology" values exporting them as rasters and interrogating them for their RGB values. These are then placed in the attribute table.
3 parameters must be passed into a script tool, which is used in a current mxd:
- 0: A Folder (used for temp files including new file gdb & layer files)
- 1: A layer (from an open mxd)
- 2: The nominated layers symbolology field
Code Sample:
import arcpy
from arcpy import env
arcpy.gp.overwriteOutput = True
arcpy.AddMessage("STARTED")
arcpy.AddMessage(" ")
arcpy.AddMessage("======================================================================")
##############
Folder = arcpy.GetParameterAsText(0)
if Folder == '#' or not Folder:
Folder = "C:\\Data"
##############
GDB = Folder+"\\TempGDB.gdb"
if arcpy.Exists(GDB):
arcpy.AddMessage(GDB)
else:
arcpy.CreateFileGDB_management(Folder, "TempGDB")
arcpy.AddMessage("GDB MADE")
# MUST BE IN ARCMAP
##############
InPolyLayer = arcpy.GetParameterAsText(1)
desc = arcpy.Describe(InPolyLayer)
LayerPath = desc.catalogPath
arcpy.AddMessage("Path: "+ LayerPath)
spatial_ref = arcpy.Describe(LayerPath).spatialReference
arcpy.AddMessage("Spatial Reference: "+spatial_ref.name)
sr = arcpy.SpatialReference(spatial_ref.factoryCode)
# Must Be The Symbology Field From "InPolyLayer"
##############
FieldName = arcpy.GetParameterAsText(2)
arcpy.AddMessage(FieldName)
fields = arcpy.ListFields(LayerPath)
for field in fields:
if field.name == FieldName:
FType = (field.type)
FPrecision = (field.precision)
FScale = (field.scale)
FLength = (field.length)
FNull = (field.isNullable)
arcpy.AddMessage("Type: "+str(FType))
arcpy.AddMessage("Precision: "+str(FPrecision))
arcpy.AddMessage("Scale: "+str(FScale))
arcpy.AddMessage("Lenght: "+str(FLength))
arcpy.AddMessage("Null: "+ str(FNull))
TempTileFC = GDB+"\\TempTileFC"
if arcpy.Exists(TempTileFC):
arcpy.Delete_management(TempTileFC)
### Varibles
# Temps
TempFrequency = GDB+"\\TempFrequency"
if arcpy.Exists(TempFrequency):
arcpy.Delete_management(TempFrequency)
TempP = GDB+"\\TempP"
if arcpy.Exists(TempP):
arcpy.Delete_management(TempP)
TRaster = Folder+"\\TempRaster.tif"
arcpy.AddMessage("TEMPS SET")
# Layers
mxd = arcpy.mapping.MapDocument ("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
TempLayerName = "TempLayer"
FreqView = "FreqView"
TempLayerFile = Folder+"\\TempLayerFile.lyr"
TempLayerFileLayer = "TempLayerFileLayer"
TempLayerCloneName = "TempLayerClone"
#Lyr for raster
arcpy.SaveToLayerFile_management(InPolyLayer, TempLayerFile, "ABSOLUTE")
# Fields
FieldNameR = str(FieldName)+"_R" #Check for, and create RGB Field
FieldNameG = str(FieldName)+"_G" #Check for, and create RGB Field
FieldNameB = str(FieldName)+"_B" #Check for, and create RGB Field
if len(arcpy.ListFields(InPolyLayer,FieldNameR)) == 0:
arcpy.AddField_management (InPolyLayer, FieldNameR, "short")
arcpy.AddMessage(FieldNameR +" field created")
else:
arcpy.AddMessage(FieldNameR +" field exists")
if len(arcpy.ListFields(InPolyLayer,FieldNameG)) == 0:
arcpy.AddField_management (InPolyLayer, FieldNameG, "short")
arcpy.AddMessage(FieldNameG +" field created")
else:
arcpy.AddMessage(FieldNameG +" field exists")
if len(arcpy.ListFields(InPolyLayer,FieldNameB)) == 0:
arcpy.AddField_management (InPolyLayer, FieldNameB, "short")
arcpy.AddMessage(FieldNameB +" field created")
else:
arcpy.AddMessage(FieldNameB +" field exists")
arcpy.AddMessage(" ")
arcpy.AddMessage("======================================================================")
arcpy.AddMessage(" ")
arcpy.AddMessage(" * FREQUENCIES & TEMP CARTO TILES")
arcpy.Frequency_analysis(LayerPath, TempFrequency, FieldName, "")
arcpy.AddMessage(" - Symbology Frequency Analysis Completed")
# Make Polygon For Layer Symbol Export
xExtent = df.extent
pnt1 = arcpy.Point(xExtent.XMin , xExtent.YMin)
pnt2 = arcpy.Point(xExtent.XMax , xExtent.YMin)
pnt3 = arcpy.Point(xExtent.XMax , xExtent.YMax)
pnt4 = arcpy.Point(xExtent.XMin , xExtent.YMax)
array = arcpy.Array()
array.add(pnt1)
array.add(pnt2)
array.add(pnt3)
array.add(pnt4)
array.add(pnt1)
SYMExtent = arcpy.Polygon(array)
arcpy.FeatureClassToFeatureClass_conversion (SYMExtent, GDB, "TempTileFC", "", "", "")
arcpy.AddMessage(" - Temp Tile Feature Class: "+str(TempTileFC))
arcpy.AddField_management (TempTileFC, FieldName, FType, FPrecision, FScale, FLength, "", FNull, "", "")
arcpy.FeatureToPoint_management (SYMExtent, TempP, "CENTROID")
TempPCen = arcpy.Describe(TempP)
CentroidE = TempPCen.extent
CentroidX = CentroidE.XMin
CentroidY = CentroidE.YMin
arcpy.AddMessage(" - Temp Tile Feature Class Field Added:"+str(FieldName))
arcpy.AddMessage(" - Centroid Feature Class For Raster:"+str(CentroidX)+str(CentroidY))
sourceLayer = arcpy.mapping.Layer(TempLayerFile)
arcpy.AddMessage(" ")
arcpy.AddMessage("======================================================================")
arcpy.AddMessage(" ")
arcpy.AddMessage(" * LOOPING VALUES")
cursor = arcpy.SearchCursor(TempFrequency)
for row in cursor:
arcpy.AddMessage(" ")
arcpy.AddMessage(" --------------")
rec = row.getValue(FieldName)
arcpy.AddMessage(" - Frequency Field Name:"+str(FieldName))
arcpy.AddMessage(" - Frequency Record: "+str(rec))
TempLayerClone = TempLayerCloneName+str(rec)
arcpy.AddMessage(" - Temp Layer:"+str(TempLayerClone))
### We don't need to delete the geom. just write the new value.
FieldExp ="'"+str(rec)+"'"
arcpy.AddMessage(" - Calculate Tile Field Expression: "+str(FieldExp))
arcpy.AddMessage(" - Temp Tile: " +str(TempTileFC))
arcpy.CalculateField_management(TempTileFC, FieldName, FieldExp, "PYTHON_9.3","")
# Remove Layer Test
for df in arcpy.mapping.ListDataFrames(mxd):
for lyr in arcpy.mapping.ListLayers(mxd, "", df):
if str(lyr)==TempLayerClone:
arcpy.mapping.RemoveLayer(df, lyr)
if arcpy.Exists(TempLayerClone):
arcpy.Delete_management(TempLayerClone)
# Make Layer
arcpy.MakeFeatureLayer_management (TempTileFC, TempLayerClone, "", "", "") # Make Layer
FeatureClassLayerMapping = arcpy.mapping.Layer(TempLayerClone)
arcpy.mapping.AddLayer(df, FeatureClassLayerMapping, "TOP") # Layer At Top
arcpy.AddMessage(" - Layer Added")
# Update
df2 = arcpy.mapping.ListDataFrames(mxd)[0]
updateLayer2 = arcpy.mapping.ListLayers(mxd, TempLayerClone, df)[0]
arcpy.mapping.UpdateLayer(df2, updateLayer2, sourceLayer, "True") # Carto Matches
################ NUMERIC OR TEXT
if FType == "String":
arcpy.AddMessage(" - IS String")
## 10.1
DefQURY = (("""\"{0}"='{1}'""").format(FieldName,rec)) #TEXT FIELDS
elif FType == "Text":
arcpy.AddMessage(" - IS TEXT")
## 10.1
DefQURY = (("""\"{0}"='{1}'""").format(FieldName,rec)) #TEXT FIELDS
else:
arcpy.AddMessage(" - IS NOT TEXT")
DefQURY = (("""\"{0}"={1}""").format(FieldName,rec)) #NUMERIC FIELDS
arcpy.AddMessage(" - Layer Updated")
arcpy.AddMessage(" - Selection Qu:" +str(DefQURY))
arcpy.SelectLayerByAttribute_management (updateLayer2, "NEW_SELECTION", DefQURY ) # Select & Zoom
df.zoomToSelectedFeatures()
arcpy.SelectLayerByAttribute_management (updateLayer2, "CLEAR_SELECTION")
arcpy.RefreshActiveView()
arcpy.AddMessage(" - Zoomed")
#Raster
if arcpy.Exists(TRaster):
arcpy.Delete_management(TRaster)
arcpy.mapping.ExportToTIFF(mxd, TRaster, df2, df_export_width=600,df_export_height=600,geoTIFF_tags=True)
arcpy.AddMessage(" - RGB Raster Exported")
arcpy.AddMessage(" - RGB Raster: "+TRaster)
Centroidf = ("{0} {1}".format(CentroidX,CentroidY))
RValues = arcpy.GetCellValue_management(TRaster, Centroidf, "1")
GValues = arcpy.GetCellValue_management(TRaster, Centroidf, "2")
BValues = arcpy.GetCellValue_management(TRaster, Centroidf, "3")
arcpy.AddMessage(" - R: "+str(RValues))
arcpy.AddMessage(" - G: "+str(GValues))
arcpy.AddMessage(" - B: "+str(BValues))
#Selection
arcpy.SelectLayerByAttribute_management (InPolyLayer, "NEW_SELECTION", DefQURY )
arcpy.AddMessage(" - Selection: "+ InPolyLayer)
arcpy.AddMessage(" - Def: "+ DefQURY)
arcpy.CalculateField_management(InPolyLayer, FieldNameR, RValues, "PYTHON_9.3")
arcpy.CalculateField_management(InPolyLayer, FieldNameG, GValues, "PYTHON_9.3")
arcpy.CalculateField_management(InPolyLayer, FieldNameB, BValues, "PYTHON_9.3")
arcpy.SelectLayerByAttribute_management (InPolyLayer, "CLEAR_SELECTION", DefQURY )
arcpy.AddMessage(" - Calculated & Cleared")
# Remove Layer
for df3 in arcpy.mapping.ListDataFrames(mxd):
for lyr in arcpy.mapping.ListLayers(mxd, "", df3):
if str(lyr)==TempLayerClone:
arcpy.mapping.RemoveLayer(df3, lyr)
del TempLayerClone
del FeatureClassLayerMapping
del df2, df3
arcpy.AddMessage(" - Removed & Cleared")
## if current is not saved then the tool will fail
mxd.save()
Example: enter image description here
-
1I wrote the above py to be a script tool. The 3 exposed parameters plug into the toolbox tool nicely. Here's how you make a script tool: help.arcgis.com/EN/arcgisdesktop/10.0/help/index.html#/…GISI– GISI2015年08月28日 07:22:57 +00:00Commented Aug 28, 2015 at 7:22
-
Can you write down some information what types of parameters did you use for Symbology field when creating a script tool.MihaK– MihaK2017年02月06日 17:27:23 +00:00Commented Feb 6, 2017 at 17:27
Explore related questions
See similar questions with these tags.