আর্কজিআইএস 10 - আর্কপাইতে "ফিল্ড ম্যাপিং"


13

আমি একটি পাইথন স্ক্রিপ্ট লিখেছি যা একটি স্থানিক যোগদান এবং কিছু সাধারণ গণনা করে। আমার সমস্যাটি একটি নির্দিষ্ট ক্ষেত্রের জন্য একত্রীকরণের নিয়ম নির্ধারণ এবং বাকী ক্ষেত্রগুলি যেমন রয়েছে তেমনটি নিয়ে। উদাহরণস্বরূপ, আমার একটি জনসংখ্যার ক্ষেত্র রয়েছে যা স্থানিক অবস্থানের সাথে যোগদানের পরে মার্জ নিয়ম "প্রথম" ব্যবহার করে যা জনসংখ্যার গণনার প্রথম ঘটবে। আমি একত্রীকরণ নিয়ম সেট করতে সক্ষম হতে চান "যোগফল" থেকে বহুভুজ অন্য বহুভুজ স্থানিক ব্যাপ্তি পাওয়া এতদুভয়ের মধ্যবর্তী সব কিছুর জনসংখ্যা মান পর্যন্ত যোগ

আমি ফিল্ড মানচিত্র এবং ফিল্ড ম্যাপিং অবজেক্টগুলির সাথে কিছু তীব্র টিঙ্কারিং করেছি, তবে এটি সঠিকভাবে কাজ করছে বলে মনে হচ্ছে না। বিশেষত আমি পদ্ধতিটি ব্যবহার করে দেখেছি : পপফিল্ডম্যাপ.মিটারল = 'যোগফল' সেট করার জন্য 'সম' , তবে এটি সর্বদা "প্রথম" এ ফিরে আসে।

কোন ধারণা আমি কীভাবে প্রোগ্রামিয়ালি একটি স্পেসিয়াল যোগদানের জন্য একটি ক্ষেত্রের জন্য মার্জ নিয়ম পরিবর্তন করতে পারি?

ধন্যবাদ!

এখানে আমার কোড (মনে রাখবেন যে এটি আমার ডেটার সাথে বেশ নির্দিষ্ট এবং এতে স্ক্রিপ্টের কয়েকটি নির্দিষ্ট স্তর পরীক্ষা করার জন্য লাইন রয়েছে):

import arcpy,sys,os

#Get the Files involved, set some variables.
SectorTable = sys.argv[1]
SectorShape = sys.argv[2]
MaxDev = sys.argv[3]
PopulationFC = sys.argv[4]
OutputFC = sys.argv[5]
DeviationField ="Angle_Deviation"
ID = "SectorID"
newID = "BP_ID"
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]

#Check to see if ID field types and name match
try:
    SectorShapeFields = arcpy.ListFields (SectorShape,ID)
    SectorTableFields = arcpy.ListFields (SectorTable,ID)
    arcpy.AddMessage("Finished Listing Fields")
    nameCheck = SectorShapeFields[0].name == SectorTableFields[0].name
    typeCheck = SectorShapeFields[0].type == SectorTableFields[0].type
except:
    arcpy.AddMessage("Failed to List Fields")

#If they do not match, add new fields to correct.
if not nameCheck:
    arcpy.AddMessage("Field Names do not match!  Adding new field to circumvent...")
if not typeCheck:
    arcpy.AddMessage("Field Types do not match!  Adding new field to circumvent...")
    if SectorShapeFields[0].type != SectorTableFields[0].type:
        try:
            arcpy.AddField_management(SectorShape, newID, SectorTableFields[0].type,10)
            arcpy.CalculateField_management(SectorShape, newID,"!"+ID+"!", "PYTHON")
            arcpy.RefreshTOC()
        except:
            arcpy.AddMessage("Error in Creating Field. Does it already exist?")


#Join the two together
arcpy.AddMessage("Performing Join")
arcpy.AddJoin_management( SectorShape, newID, SectorTable, ID)
arcpy.SelectLayerByAttribute_management (SectorShape,"NEW_SELECTION","Angle_Deviation>"+str(MaxDev))
df.zoomToSelectedFeatures()

#Field Mapping ...
myMap = arcpy.FieldMappings()
myMap.addTable(PopulationFC)
myMap.addTable(SectorShape)

#Verify the field merge rule for the pop10 field.
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap.mergeRule = 'Sum'
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap2 = popFieldMap

##Test
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))

#Perform Spatial Join
arcpy.AddMessage("Performing Spatial Join")
arcpy.SpatialJoin_analysis(SectorShape, PopulationFC, OutputFC,"JOIN_ONE_TO_ONE","",myMap,"INTERSECT")

#Add Result and Symbolize
arcpy.mapping.AddLayer(df,arcpy.mapping.Layer(OutputFC))
translayer = arcpy.mapping.ListLayers(mxd,"",df)[0]
translayer.transparency = 50

arcpy.RefreshActiveView()

সম্পাদনা - সমাধানটি প্রয়োগের সাথে নীচে কোডটি দেওয়া হল!

import arcpy,sys,os

#Get the Files involved, set some variables.
SectorTable = sys.argv[1]
SectorShape = sys.argv[2]
MaxDev = sys.argv[3]
PopulationFC = sys.argv[4]
OutputFC = sys.argv[5]
DeviationField ="Angle_Deviation"
ID = "SectorID"
newID = "BP_ID"
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd)[0]

#Check to see if ID field types and name match
try:
    SectorShapeFields = arcpy.ListFields (SectorShape,ID)
    SectorTableFields = arcpy.ListFields (SectorTable,ID)
    arcpy.AddMessage("Finished Listing Fields")
    nameCheck = SectorShapeFields[0].name == SectorTableFields[0].name
    typeCheck = SectorShapeFields[0].type == SectorTableFields[0].type
except:
    arcpy.AddMessage("Failed to List Fields")

#If they do not match, add new fields to correct.
if not nameCheck:
    arcpy.AddMessage("Field Names do not match!  Adding new field to circumvent...")
if not typeCheck:
    arcpy.AddMessage("Field Types do not match!  Adding new field to circumvent...")
    if SectorShapeFields[0].type != SectorTableFields[0].type:
        try:
            arcpy.AddField_management(SectorShape, newID, SectorTableFields[0].type,10)
            arcpy.CalculateField_management(SectorShape, newID,"!"+ID+"!", "PYTHON")
            arcpy.RefreshTOC()
        except:
            arcpy.AddMessage("Error in Creating Field. Does it already exist?")


#Join the two together
arcpy.AddMessage("Performing Join")
arcpy.AddJoin_management( SectorShape, newID, SectorTable, ID)
arcpy.SelectLayerByAttribute_management (SectorShape,"NEW_SELECTION","Angle_Deviation>"+str(MaxDev))
df.zoomToSelectedFeatures()

#Field Mapping ...
myMap = arcpy.FieldMappings()
myMap.addTable(PopulationFC)
myMap.addTable(SectorShape)

#Verify the field merge rule for the pop10 field.
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))
popFieldMap.mergeRule = 'Sum'
arcpy.AddMessage(str(popFieldMap.mergeRule))

myMap.replaceFieldMap(fIndex,popFieldMap)

##Test
fIndex = myMap.findFieldMapIndex("POP10")
arcpy.AddMessage(str(fIndex))
popFieldMap = myMap.getFieldMap(fIndex)
arcpy.AddMessage(str(popFieldMap.mergeRule))

#Perform Spatial Join
arcpy.AddMessage("Performing Spatial Join")
arcpy.SpatialJoin_analysis(SectorShape, PopulationFC, OutputFC,"JOIN_ONE_TO_ONE","",myMap,"INTERSECT")

#Add Result and Symbolize
arcpy.mapping.AddLayer(df,arcpy.mapping.Layer(OutputFC))
translayer = arcpy.mapping.ListLayers(mxd,"",df)[0]
translayer.transparency = 50

arcpy.RefreshActiveView()

1
আপনি কি আপনার স্ক্রিপ্ট পোস্ট করতে পারেন?
blah238

অবশ্যই, আমাকে এটি পোস্ট করতে দিন। মনে রাখবেন যে আমার কোডের কিছু অংশ রয়েছে যা আমি পরীক্ষার পদক্ষেপ হিসাবে sertedোকালাম।
পিক্সেল

আপনি কি populationক্ষেত্রের ডেটা ধরণের পরীক্ষা করেছেন ?
অ্যালেক্স মার্কভ

আমার প্রথম প্রবণতাটি সম্ভবত পপ ক্ষেত্রটি একটি পাঠ্যের ধরণ।
ব্র্যাড নেসোম

মাঠের ধরণটি "লম্বা", সুতরাং এটি গাণিতিক সংশ্লেষ সম্পাদনের যোগ্য হওয়া উচিত, তাই না?
পিক্সেল

উত্তর:


14

আমি মনে করি FieldMappings.replaceFieldMapএটি চালিয়ে যাওয়ার জন্য আপনার আসলে ব্যবহার করা উচিত। সহায়তা বিষয় থেকে ইনপুট ক্ষেত্রগুলিকে আউটপুট ক্ষেত্রগুলিতে ম্যাপিংয়ের উদাহরণ :

# First get the TRACT2000 fieldmap. Then add the TRACTCODE field
#   from Blocks2 as an input field. Then replace the fieldmap within
#   the fieldmappings object.
#
fieldmap = fieldmappings.getFieldMap(fieldmappings.findFieldMapIndex("TRACT2000"))
fieldmap.addInputField(fc2, "TRACTCODE")
fieldmappings.replaceFieldMap(fieldmappings.findFieldMapIndex("TRACT2000"), fieldmap)

আরেকটি চিন্তাভাবনা হ'ল ক্ষেত্রের মানচিত্রগুলি পরীক্ষা করার সময়, আমি একটি স্ক্রিপ্ট সরঞ্জাম এবং কাস্টম স্ক্রিপ্ট সরঞ্জাম আচরণ ব্যবহার করতে পছন্দ করি যাতে তারা উত্পাদিত পাগল দীর্ঘ স্ট্রিংগুলি ডিকোড করার পরিবর্তে ক্ষেত্রের মানচিত্রটি দৃশ্যত পরিদর্শন করতে পারি।

উদাহরণস্বরূপ ToolValidatorক্লাসটি আমি এই উপসংহারে ব্যবহার করেছিলাম যে হ্যাঁ, replaceFieldMapএটির জন্য প্যারামিটারের মানটি বজায় রাখতে হবে:

class ToolValidator:
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    import arcpy
    self.params = arcpy.GetParameterInfo()

  def initializeParameters(self):
    """Refine the properties of a tool's parameters.  This method is
    called when the tool is opened."""
    return

  def updateParameters(self):
    """Modify the values and properties of parameters before internal
    validation is performed.  This method is called whenever a parmater
    has been changed."""
    if (not self.params[0].hasBeenValidated
    or not self.params[1].hasBeenValidated):
        targetFeatures = self.params[0].value
        joinFeatures = self.params[1].value
        fieldMappings = arcpy.FieldMappings()
        if targetFeatures:
            fieldMappings.addTable(targetFeatures)
            if joinFeatures:
                fieldMappings.addTable(joinFeatures)
                idx = fieldMappings.findFieldMapIndex("PRIORITY")
                fieldMap = fieldMappings.getFieldMap(idx)
                fieldMap.mergeRule = 'Sum'
                fieldMappings.replaceFieldMap(idx, fieldMap) # if this line is commented out, the merge rule reverts to 'First'
        self.params[3].value = fieldMappings.exportToString()
    return

  def updateMessages(self):
    """Modify the messages created by internal validation for each tool
    parameter.  This method is called after internal validation."""
    return

খুব ভাল লাগলো, আমাকে এটি সন্ধান করা যাক এবং আমার স্ক্রিপ্টে আমি এটি কোথায় প্রয়োগ করব। আমি আমার অনুসন্ধানগুলি নিয়ে পোস্ট করব
পিক্সেল

2
এটি একটি দুর্দান্ত উত্তর যা সমস্যার সমাধান করেছিল। এছাড়াও, সমস্যার কারণ হিসাবে দুর্দান্ত বিশদ দেওয়ার জন্য ধন্যবাদ! :)
পিক্সেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.