1. 程式人生 > >pycharm在arcpy開發中arcgis工具箱打包

pycharm在arcpy開發中arcgis工具箱打包

明天就國慶了,剛好最近在使用python在arcgis方面批處理開發工作,寫了一些總結,以備後用。

這次我們先做了一個測試工具,其主要目的是利用toolbox工具箱的Mosaic To New Raster將多個柵格資料合成一個柵格資料。如果說柵格數量少的話,手動選擇並沒有太大的影響。而如果柵格檔案非常多的話,手動選擇將浪費大量的時間和精力,為此我們寫了一個小工具,將某個目錄下所有的柵格資料一次性加入到上面的Mosaic To New Raster工具中,直接執行即可。說得直接一點就是直接呼叫了Mosaic To New Raster工具,一次性加入多個檔案。在寫完這個工具後遇到工具打包和工具多個引數型別問題,現將自己寫這部分功能中遇到的問題特記錄下來。

利用python呼叫arcpy指令碼後,如果使用程式碼的方式讓使用者使用編寫的指令碼是極其的不方便和友好。為此,需要利用某種方式將寫好的指令碼程式碼封裝成類似arcgis中工具箱的工具。將寫好的程式碼的目錄利用catalog將其新增到arcgis中,然後在arcgis中選擇該目錄,右擊選擇【New】、選擇【Python ToolBox】。這樣在該目錄下就生成了Toolbox.pyt檔案。具體操作如下圖所示。

接下來利用pycharm再次將剛才的目錄匯入,也可以不用該步驟。如下圖所示,可以看到有新生成的三個檔案。如果pyt字尾的檔案,在pycharm中為灰色,那麼說明該字尾的pyt的python程式碼沒有被pycharm所識別,如何解決這個問題,可以參考之前寫的部落格

pycharm匯入.pyt字尾檔案

首先我們在單獨檔案python檔案中,寫了我們功能函式,而我們現在需要配置引數,將我們需要的引數傳入到具體的功能函式中。具體來說就是做成類似下面的將多個數據原始檔合併成新的一個檔案。每個輸入框對應這我們功能函式的一個引數。

函式中,新增如下程式碼對應的引數。注意每個引數都有displayName、name、dataType、paramterType、direction引數,分別代表這在工具框顯示名稱,對應名稱,資料型別、引數型別、方式(必須還是可選)。在這裡我們利用到dataType資料型別有Folder(目錄)、GPString(字元)、Long(長形資料)、GPSpatialReference(空間參考)、同時有選選項還會出現是選擇框型別,可以對引數的屬性filter.type=”ValueList”、對應列舉相應的值,如filter.list=[“11”,”22”,”33”]、設定選擇框的預設選擇值可利用引數的value屬性設定,具體引數可以參考程式碼。最後做成如下的結果介面。是不是感覺和Mosaic To New Raster工具非常像。

在ToolBox.pyt,彈出框配置輸入引數程式碼如下:

# coding:gbk
import arcpy

from MosaicToNewRaster import doExcute


class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "Toolbox"
        self.alias = ""

        # List of tool classes associated with this toolbox
        self.tools = [Tool]


class Tool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "批量合成某一目錄下所有的tif"
        self.description = "批量合成某一目錄下所有的tif"
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        dataFolder=arcpy.Parameter(
            displayName="資料資料夾",
            name="dataFolder",
            datatype="Folder",
            parameterType="Required",
            direction="Input"

        )


        exTension=arcpy.Parameter(
            displayName="資料集名稱以及副檔名",
            name="exTension",
            datatype="GPString",
            parameterType="Required",
            direction="Input"
        )

        bandNums=arcpy.Parameter(
            displayName="波段數",
            name="bandNums",
            datatype="Long",
            parameterType="Required",
            direction="Input"

        )
        resultFolder = arcpy.Parameter(
            displayName="最終處理結果",
            name="resultFolder",
            datatype="Folder",
            parameterType="Required",
            direction="Input"
        )

        spatialReference=arcpy.Parameter(
            displayName="空間參考",
            name="spatialReference",
            datatype="GPSpatialReference",
            parameterType="Optional",
            direction="Input"
        )
        #設定預設值
        spatialReference.defaultEnvironmentName = "#"

        pixelType=arcpy.Parameter(
            displayName="pixelType(Optional)",
            name="pixelType",
            datatype="GPString",
            parameterType="Optional",
            direction="Input"
        )
        pixelType.filter.type = "ValueList"
        pixelType.filter.list = ["1_BIT","2_BIT","4_BIT","8_BIT_UNSIGNED","8_BIT_SIGNED","16_BIT_UNSIGNED",
                           "16_BIT_SIGNED","32_BIT_UNSIGNED","32_BIT_SIGNED","32_BIT_FLOAT","64_BIT"]
        pixelType.defaultEnvironmentName = "8_BIT_UNSIGNED"
        pixelType.value="8_BIT_UNSIGNED"


        mosaicOp=arcpy.Parameter(
            displayName="Mosaic Oprator(Optional)",
            name="mosaicOp",
            datatype="GPString",
            parameterType="Optional",
            direction="Input"
        )
        mosaicOp.filter.type = "ValueList"
        mosaicOp.filter.list = ["FIRST","LAST","BLEND","MEAN","MINIMUM","MAXIMUM","SUM"]
        mosaicOp.defaultEnvironmentName = "LAST"
        mosaicOp.value="LAST"


        mosaicColormap=arcpy.Parameter(
            displayName="Mosaic ColorMap Mode(Optional)",
            name="mosaicColormap",
            datatype="GPString",
            parameterType="Optional",
            direction="Input"
        )
        mosaicColormap.filter.type = "ValueList"
        mosaicColormap.filter.list = ["REJECT","FIRST","LAST","MATCH"]
        mosaicColormap.defaultEnvironmentName = "FIRST"
        mosaicColormap.value="FIRST"

        params = [dataFolder,resultFolder,exTension,spatialReference,pixelType,bandNums, mosaicOp,mosaicColormap]
        return params

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

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

    def execute(self, parameters, messages):
        """The source code of the tool."""
        dataFolder = parameters[0].valueAsText
        resultFolder=parameters[1].valueAsText
        exTension = parameters[2].valueAsText
        spatialReference = parameters[3].valueAsText
        pixelType = parameters[4].valueAsText
        bandNums = parameters[5].valueAsText
        mosaicOp = parameters[6].valueAsText
        mosaicColormap = parameters[7].valueAsText
        doExcute(dataFolder,resultFolder,exTension,spatialReference,pixelType,bandNums,mosaicOp,mosaicColormap)
        return

 資料融合程式碼相對來說比較簡單,現在貼一下比較核心的程式碼段:


# coding:utf-8
import arcpy
import shutil,os


def del_file(path):
    ls = os.listdir(path)
    for i in ls:
        c_path = os.path.join(path, i)
        if os.path.isdir(c_path):
            del_file(c_path)
        else:
            os.remove(c_path)

def list_all_files(rootdir):

       _files = []
       list = os.listdir(rootdir)  # 列出資料夾下所有的目錄與檔案
       for i in range(0, len(list)):
             path = os.path.join(rootdir, list[i])
             if os.path.isdir(path):
                _files.extend(list_all_files(path))
             if os.path.isfile(path):
                 _files.append(path)
       return _files

def list_all_dir(rootdir):
    _files=[]
    list=os.listdir(rootdir)
    return list

def containVarInString(containVar,stringVar):
    try:
        if isinstance(stringVar, str):
            if stringVar.find(containVar):
                return True
            else:
                return False
        else:
            return False
    except Exception,e:
        print e

#http://www.mamicode.com/info-detail-2313739.html

#def doExcute(dataPath,bandNums,resultRoot):
def  doExcute(dataFolder, resultFolder, exTension, spatialReference, pixelType, bandNums, mosaicOp, mosaicColormap):

  dataPath=dataFolder+"/"
  print "結果路徑"
  print resultFolder
  imgArray=[]
  listDir=list_all_dir(dataPath)
  for row in listDir:
     dirFileName=row
     tmpFileDir=dataPath+str(dirFileName)

     #如果檔案存在
     if os.path.exists(tmpFileDir):

      dataResource=tmpFileDir+"/"+dirFileName
      imgArray.append(dataResource);



  strDataRoot=""

  for item in  imgArray:
    print item

  length=len(imgArray)
  for index in range(len(imgArray)):
     if index==0:
       strDataRoot=imgArray[index]
     else:
      strDataRoot = strDataRoot + ";" + imgArray[index]




  arcpy.MosaicToNewRaster_management(input_rasters=strDataRoot,
                                   output_location=resultFolder,
                                   raster_dataset_name_with_extension=exTension,
                                   coordinate_system_for_the_raster=spatialReference,
                                   pixel_type=pixelType,
                                     cellsize="#",
                                   number_of_bands=bandNums,
                                   mosaic_method=mosaicOp,
                                   mosaic_colormap_mode=mosaicColormap)






至此,整個講解就說明完了。更多相關arcpy的開發,將需要不斷學習。

                                                                                 更多內容,請關注公眾號