diff --git a/MSBuffer_v1_0_0/MSBuffer_v1_0_0.py~ b/MSBuffer_v1_0_0/MSBuffer_v1_0_0.py~
index dca800a..23c4b44 100644
--- a/MSBuffer_v1_0_0/MSBuffer_v1_0_0.py~
+++ b/MSBuffer_v1_0_0/MSBuffer_v1_0_0.py~
@@ -1,384 +1,384 @@
-#---------------------------------------------------------------------------------------
-"""
- MSbuffer - MultiScale Buffer Analysis
-
- Bruno P. Leles - brunopleles@gmail.com
- Bernardo B. S. Niebuhr - bernardo_brandaum@yahoo.com.br
- John W. Ribeiro - jw.ribeiro.rc@gmail.com
- Juliana Silviera dos Santos - juliana.silveiradossantos@gmail.com
- Camila Eboli -
- Alice C. Hughes -
- Milton C. Ribeiro - mcr@rc.unesp.br
-
- Universidade Estadual Paulista - UNESP
- Rio Claro - SP - Brasil
-
- This script runs inside ArcMap v. 10.2.1 using Python 2.7.
-.
- The Multi-Scale Buffer (MSBuffer) is a free and open source package developed in the Python 2.7
- as an ArcGIS geoprocessing tool. It that performs area/length calculation and feature counting in buffers
- of multiple sizes around of an area of interest.
-
- Usage: Take a look at the online tutorial at https://github.com/LEEClab/MSBuffer.
-
- Copyright (C) 2017 by Bruno P. Leles, Bernardo B. S. Niebuhr, John W. Ribeiro, and Milton C. Ribeiro.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 2 of the license,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-"""
-#---------------------------------------------------------------------------------------
-
-#------------------------------
-# Import modules
-import arcpy
-from arcpy import env
-import os, sys
-import arcpy.mapping
-
-#------------------------------
-# Name of the geo database where output buffer maps will be saved
-geoDB_name = "output_buffer_maps.gdb"
-# Do we want to overwrite output buffer maps in case the analysis is re-run?
-overwrite_maps = True
-
-#------------------------------
-# Reading parameters from the GUI
-
-# Input map
-inputmap = arcpy.GetParameterAsText(0) # input map
-inputCol = arcpy.GetParameterAsText(1) # column of the input map, correspondent to the variable of interest
-inputmap_name = inputmap.split("\\") # extracting the name of the input map
-inputmap_name = inputmap_name[-1].replace(".shp", '') # name of the input map (without the path)
-
-# Input variable of interest
-variable_interest = arcpy.GetParameterAsText(2) # map of the variable of interest
-variable_interest_name = variable_interest.split('\\') # extracting the name of the variable of interest map
-variable_interest_name = variable_interest_name[-1].replace('.shp', '') # name of the variable of interest map (without the path)
-
-# Scale (buffer size in meters)
-scale = arcpy.GetParameterAsText(3)
-scale = int(scale)
-
-# Number of buffers
-nbuffers = arcpy.GetParameterAsText(4)
-nbuffers = int(nbuffers)
-
-# Should we count the number of features?
-count_on_off = arcpy.GetParameterAsText(5) # boolean to count features
-#feature_to_count = variable_interest
-
-# Should we calculate the area or length inside the buffer?
-area_length_on_off = arcpy.GetParameterAsText(6) # boolean to calculate area or length inside the donut buffer
-
-# Should we calculate Functional Area (in case of a polygon variable of interest)?
-func_area_length_on_off = arcpy.GetParameterAsText(7) # boolean to calculate functional area or length
-
-# Save output maps?
-save_maps = arcpy.GetParameterAsText(8) # boolean to save buffer maps in the geodatabase
-
-# Prefix for output files
-OutPutTxt = arcpy.GetParameterAsText(9)
-
-# Folder for output files
-OutPutFolder = arcpy.GetParameterAsText(10)
-
-
-#----------------------------------------------------------------------------------
-# MSBuffer is the main class, in which the toolbox is initialized and runs
-
-class MSBuffer(object):
-
- # Initializing parameters
- def __init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
- scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off):
-
- # Input maps and outputs
- self.inputmap = inputmap # Input map
- self.inputmap_name = inputmap_name # Name of the input map
- self.inputCol = inputCol # column of the input map that identifies the ID of the polygons around which the buffers will be drawn
- self.variable_interest = variable_interest # Map correspondent to the variable of interest
- self.variable_interest_name = variable_interest_name # Name of the variable of interest map
- self.OutPutTxt = OutPutTxt # Prefix of the output file names
- self.OutPutFolder = OutPutFolder # Folder where text files will be saved
- self.save_maps = save_maps # Will buffer maps be saved in the ArcGIS geodatabase?
-
- # Parameters
- self.scale = scale # Scale parameter (minimum buffer size)
- self.nbuffers = nbuffers # Number of buffers - parameter
- self.count_on_off = count_on_off # Option: count or not the number of features
- self.area_length_on_off = area_length_on_off # Option: calculate or not the area/length inside the buffer, in case the variable of interest is of the type "polygon"/"polyline"
- self.func_area_length_on_off = func_area_length_on_off # Option: calculate or not the functional area/length, in case the variable of interest is of the type "polygon"/"polyline"
-
- # Auxiliary variables
- self.isArea = False # True if the geometry of the variable of interest is Polygon
- self.isLine = False # True if the geometry of the variable of interest is Polyline
- self.isPoint = False # True if the geometry of the variable of interest is Point
-
- self.listbuffers = '' # List of buffer map names (with input map) generated by createBuffer function
- self.Listerased = '' # List of donut buffer map names (buffer without input mao) generated by erase function
- self.listclip = '' # List of maps with the variable of interest clipped by donut buffer maps, generated by clip_variable_interest_by_donut_buffer function
-
- self.list_buffer_scales = [] # List of buffer sizes (e.g., 500, 1000, 1500, 2000)
- self.ListIDcod = [] # List of ID codes - features of the input map, around which buffers will be drawn
- self.FieldList = [] # List of column names in a shapefile, used for checking if a given column exists
- self.referenceListquery = [] # List of queries: SQL expressions used to select each feature of the input map
- self.listDonutMapAreas = [] # List of total areas of Donut maps (buffer without the input map feature)
- self.countList = [] # List of number of features inside the donut buffer maps, for each buffer size
- self.listAreaInsideBuffer = [] # List of area of polygons of the variable of interest that overlap the donut buffer maps, for each buffer size
- self.listFunctionalArea = [] # List of functional area of polygons that overlap the donut buffer maps, for each buffer size
- self.listLengthInsideBuffer = [] # List of length of polylines of the variable of interest that overlap the donut buffer maps, for each buffer size
- self.listFunctionalLength = [] # List of functional length of lines that overlap the donut buffer maps, for each buffer size
-
- self.counter = 0 # Counter to identify the elements of the polygon ID list
- self.onelist = '' # Global Class List to be used by the function selectINlist
- self.pattern = '' # Global Class pattern string to be used by the function selectINlist
-
- #self.feature=feature_to_count # = variable of interest, i.e, the shapefile whose features should be counted
-
- # Output files and names
- self.txtArea = '' # Output file where area analysis will be saved
- self.txtFuncArea = '' # Output file where functional area analysis will be saved
- self.txtLength = '' # Output file where length analysis will be saved
- self.txtFuncLength = '' # Output file where functional length analysis will be saved
- self.txtCountFeat = '' # Output file where cont feature analysis will be saved
- self.txtBufferArea = '' # Output file where donut buffer areas will be saved
-
- # Names of the output files
- # Area
- self.txtArea_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Area.txt"
- # Functional area
- self.txtFuncArea_name = self.OutPutTxt+"_"+self.variable_interest_name+"_FunctionalArea.txt"
- # Length
- self.txtLength_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Length.txt"
- # Functional length
- self.txtFuncLength_name = self.OutPutTxt+"_"+self.variable_interest_name+"_FunctionalLength.txt"
- # Count feaures
- self.txtCountFeat_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Count.txt"
- # Donut buffer area
- self.txtBufferArea_name = self.OutPutTxt+"_"+self.variable_interest_name+'_BufferArea.txt'
-
- # Defining the workspace for ArcGIS as the output folder
- arcpy.env.workspace=self.OutPutFolder
-
- #------------------------
- def defineScale(self):
- '''
- Function defineScale
-
- This function reads the parameters scale (buffer size) and number of buffers
- and defines a list of buffer sizes.
- '''
-
- # Assess the minimum buffer size
- con_esc=self.scale
-
- # For each element up to the number of buffers
- for i in range(self.nbuffers):
- self.list_buffer_scales.append(con_esc) # Appending a buffer value to the buffer scale list
- con_esc=con_esc+self.scale # Defining the next buffer value
-
-
- def createInputMapIDList(self):
- '''
- Function createInputMapIDList
-
- This function creates a list of features (ID, names, ...) given the input map
- and the identificator column.
- Each component of this list corresponds to a feature of the input map.
- '''
-
- # Looking at the elements of the inputCol, within the inputmap
- with arcpy.da.SearchCursor(self.inputmap, self.inputCol) as cursor:
- for row in cursor:
- # Tries to transform the elements in interger numbers, in case numerical IDs are used
- try:
- temp=int(row[0])
- self.ListIDcod.append(temp) # Appends the value to the list of ID codes
- query="\""+self.inputCol+"\"="+`temp` # Creating SQL expression for retrieving this feature later on
- # If it is not possible, it considers the elements of the column as strings
- except:
- self.ListIDcod.append(row[0]) # Appends the value to the list of ID codes
- query = self.inputCol+"='%s'" % row[0] # Creating SQL expression for retrieving this feature later on
-
- self.referenceListquery.append(query) # Appending expression to query list
-
-
- # This function deletes pre-existing shape files in the output geodatabase
- def deleteFiles(self):
- '''
- Function deleteFiles
-
- This function deletes pre-existing shape files in the output geodatabase.
- '''
-
- # If the geodatabase exists in the output folder
- if os.path.exists(self.OutPutFolder+'/'+geoDB_name):
- # Sets the ArcGIS workspace as the geodatabase
- arcpy.env.workspace=self.OutPutFolder+'/'+geoDB_name
- # Raises a list of shape features in the geodatabase
- onelist=arcpy.ListFeatureClasses()
- # For each element in the list, deletes the feature and the shapefile
- for i in onelist:
- inp = i.replace(".shp", '')
- arcpy.Delete_management(i)
- arcpy.Delete_management(inp)
-
-
- def selectInList(self):
- '''
- Function selectInList
-
- This function looks into a list (self.onelist), search for elements that match the
- string self.pattern, and returns the list of matched elements.
- '''
-
- # Initializing list
- onelist=[]
- # For each element in a list of shapefile names
- for i in self.onelist:
- # If the string pattern is found inside the name
- if self.pattern in i:
- onelist.append(i) # Appends that to the list
-
- return onelist # Returns the list of matched elements
-
-
- def createDb(self):
- '''
- Function createDb
-
- In case the geodatabase for saving the maps does not exist, this function creates it.
- '''
-
- # If the geodatabase does not exist
- if not os.path.exists(self.OutPutFolder+'/'+geoDB_name):
- arcpy.CreateFileGDB_management(self.OutPutFolder, geoDB_name) # Create it
-
-
- def createBuffer(self):
- '''
- Function createBuffer
-
- This function generates buffer maps (which overlap the input map).
- It also defines a list of buffer map names called self.listbuffers.
- '''
-
- # Defining the geodatabase, inside the output folder, as the ArcGIS workspace
- arcpy.env.workspace=self.OutPutFolder+'/'+geoDB_name
-
- # Polygon ID info, for saving it in the buffer map name
- idcod = str(self.ListIDcod[self.counter])
-
- # For each buffer size in the list of buffer scales:
- for i in self.list_buffer_scales:
- # Format buffer size in the map name
- formatName="00000"+`i`
- formatName=formatName[-5:] # MAXIMUM BUFFER SIZE = 99999
- # Define the output buffer map name
- OutPutName=self.inputmap_name+"_ID_"+idcod+"_buffer_with_inputmap_"+formatName
- # Create buffer shapefile, with the original polygon together
- arcpy.Buffer_analysis(self.inputmap, OutPutName, i, "FULL", "FLAT", "ALL")
-
- # List features in the geodatabase, searches for the buffer ones just created,
- # and saves these names in a list called self.listbuffers
- listbuffers = arcpy.ListFeatureClasses()
- self.onelist = listbuffers
- self.pattern = idcod+"_buffer_with_inputmap_" # Pattern to be found in the map names
- self.listbuffers=MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of buffer map names
-
-
- def erase(self):
- '''
- Function erase
-
- This function erases the original input feature from the buffer map,
- resulting in a donut-like buffer.
- It also defines a list of donut buffer map names called self.Listerased,
- and a list of donut buffer map areas called self.listDonutMapAreas.
- '''
-
- # Polygon ID info, for saving it in the buffer map name
- idcod = str(self.ListIDcod[self.counter])
-
- # For each map in the list of buffer map names
- for i in self.listbuffers:
- # Define the name of the donut map, replacing "buffer" by "donut"
- out_name=i.replace("buffer_with_inputmap", "donut_buffer")
- # Erases the input map from the buffer map and produces a donut map
- arcpy.Erase_analysis(i, self.inputmap, out_name, '')
-
- # Add a field to the donut map attribute table, called "area_ha"
- arcpy.AddField_management(out_name, "area_ha", "DOUBLE", 10, 10)
- # Calculate the area of the donut, in hectares
- arcpy.CalculateField_management(out_name, "area_ha", "!shape.area@hectares!","PYTHON_9.3","#")
-
- # Assess the donut buffer map areas and append it to the list self.listDonutMapAreas
- rows = arcpy.da.SearchCursor(out_name, "area_ha")
- for row in rows:
- self.listDonutMapAreas.append(row[0])
- #self.lista_erases.append(out_name)
-
- # List features in the geodatabase, searches for the donut buffer ones just created,
- # and saves these names in a list called self.Listerased
- Listerased = arcpy.ListFeatureClasses()
- self.onelist = Listerased
- self.pattern = idcod+"_donut_buffer_" # Pattern to be found in the map names
- self.Listerased = MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of donut buffer map names
-
-
- def typeFeature(self):
- '''
- Function typeFeature
-
- This function checks the geometry type of the variable of interest (Polygon, Point) (pode Polyline ou outros????).
- This is written in a global variable (self.isArea or self.isPoint).
- PORQUE ELE CALCULA A AREA EM HA DE CADA POLIGONO DO MAPA DA VARIAVEL DE INTERESSE TODO?
- EH para definir a area funcional depois?
- '''
-
- # Get description of the variable of interest map
- desc = arcpy.Describe(self.variable_interest)
- # Look at the geometry type of the map (polygons, lines, points)
- geometryType = desc.shapeType
-
- # If the geometryType is Polygon:
- if geometryType == 'Polygon':
- self.isPoint = False # Variable type is not Point
- self.isLine = False # Variable type is not Line
- self.isArea = True # Defines the variable type as Area
-
- # If the Functional Area is to be calculated, calculate the area of the polygons of the variable of interest map
- if self.func_area_length_on_off:
- try:
- # Add field "area_ha" to the variable of interest map
- arcpy.AddField_management(self.variable_interest, "area_ha", "DOUBLE", 10, 10)
- # Calculate the area of the features within the map variable of interest, in hectares
- arcpy.CalculateField_management(self.variable_interest, "area_ha", "!shape.area@hectares!","PYTHON_9.3","#")
-
- #arcpy.CalculateField_management(self.variable_interest, "area_ha", "!shape.area@squaremeters!","PYTHON_9.3","#")
- #expression="!Area_ha!/10000" # Area_ha ou area_ha?
- #arcpy.CalculateField_management(self.variable_interest,"area_ha",expression,"PYTHON_9.3","#")
- except Exception as e:
- pass
-
- # If the geometryType is Polygon:
- elif geometryType == 'Point' or geometryType == 'Multipoint':
- self.isArea = False # Variable type is not Area
- self.isLine = False # Variable type is not Line
- self.isPoint = True # Defines the variable as Point
- elif geometryType == 'Polyline':
- self.isArea = False # Variable type is not Area
- self.isPoint = False # Variable type is not Point
+#---------------------------------------------------------------------------------------
+"""
+ MSbuffer - MultiScale Buffer Analysis
+
+ Bruno P. Leles - brunopleles@gmail.com
+ Bernardo B. S. Niebuhr - bernardo_brandaum@yahoo.com.br
+ John W. Ribeiro - john.wesley@pythongisoficlal.com
+ Juliana Silviera dos Santos - juliana.silveiradossantos@gmail.com
+ Camila Eboli -
+ Alice C. Hughes -
+ Milton C. Ribeiro - mcr@rc.unesp.br
+
+ Universidade Estadual Paulista - UNESP
+ Rio Claro - SP - Brasil
+
+ This script runs inside ArcMap v. 10.2.1 using Python 2.7.
+.
+ The Multi-Scale Buffer (MSBuffer) is a free and open source package developed in the Python 2.7
+ as an ArcGIS geoprocessing tool. It that performs area/length calculation and feature counting in buffers
+ of multiple sizes around of an area of interest.
+
+ Usage: Take a look at the online tutorial at https://github.com/LEEClab/MSBuffer.
+
+ Copyright (C) 2017 by Bruno P. Leles, Bernardo B. S. Niebuhr, John W. Ribeiro, and Milton C. Ribeiro.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the license,
+ or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+#---------------------------------------------------------------------------------------
+
+#------------------------------
+# Import modules
+import arcpy
+from arcpy import env
+import os, sys
+import arcpy.mapping
+
+#------------------------------
+# Name of the geo database where output buffer maps will be saved
+geoDB_name = "output_buffer_maps.gdb"
+# Do we want to overwrite output buffer maps in case the analysis is re-run?
+overwrite_maps = True
+
+#------------------------------
+# Reading parameters from the GUI
+
+# Input map
+inputmap = arcpy.GetParameterAsText(0) # input map
+inputCol = arcpy.GetParameterAsText(1) # column of the input map, correspondent to the variable of interest
+inputmap_name = inputmap.split("\\") # extracting the name of the input map
+inputmap_name = inputmap_name[-1].replace(".shp", '') # name of the input map (without the path)
+
+# Input variable of interest
+variable_interest = arcpy.GetParameterAsText(2) # map of the variable of interest
+variable_interest_name = variable_interest.split('\\') # extracting the name of the variable of interest map
+variable_interest_name = variable_interest_name[-1].replace('.shp', '') # name of the variable of interest map (without the path)
+
+# Scale (buffer size in meters)
+scale = arcpy.GetParameterAsText(3)
+scale = int(scale)
+
+# Number of buffers
+nbuffers = arcpy.GetParameterAsText(4)
+nbuffers = int(nbuffers)
+
+# Should we count the number of features?
+count_on_off = arcpy.GetParameterAsText(5) # boolean to count features
+#feature_to_count = variable_interest
+
+# Should we calculate the area or length inside the buffer?
+area_length_on_off = arcpy.GetParameterAsText(6) # boolean to calculate area or length inside the donut buffer
+
+# Should we calculate Functional Area (in case of a polygon variable of interest)?
+func_area_length_on_off = arcpy.GetParameterAsText(7) # boolean to calculate functional area or length
+
+# Save output maps?
+save_maps = arcpy.GetParameterAsText(8) # boolean to save buffer maps in the geodatabase
+
+# Prefix for output files
+OutPutTxt = arcpy.GetParameterAsText(9)
+
+# Folder for output files
+OutPutFolder = arcpy.GetParameterAsText(10)
+
+
+#----------------------------------------------------------------------------------
+# MSBuffer is the main class, in which the toolbox is initialized and runs
+
+class MSBuffer(object):
+
+ # Initializing parameters
+ def __init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
+ scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off):
+
+ # Input maps and outputs
+ self.inputmap = inputmap # Input map
+ self.inputmap_name = inputmap_name # Name of the input map
+ self.inputCol = inputCol # column of the input map that identifies the ID of the polygons around which the buffers will be drawn
+ self.variable_interest = variable_interest # Map correspondent to the variable of interest
+ self.variable_interest_name = variable_interest_name # Name of the variable of interest map
+ self.OutPutTxt = OutPutTxt # Prefix of the output file names
+ self.OutPutFolder = OutPutFolder # Folder where text files will be saved
+ self.save_maps = save_maps # Will buffer maps be saved in the ArcGIS geodatabase?
+
+ # Parameters
+ self.scale = scale # Scale parameter (minimum buffer size)
+ self.nbuffers = nbuffers # Number of buffers - parameter
+ self.count_on_off = count_on_off # Option: count or not the number of features
+ self.area_length_on_off = area_length_on_off # Option: calculate or not the area/length inside the buffer, in case the variable of interest is of the type "polygon"/"polyline"
+ self.func_area_length_on_off = func_area_length_on_off # Option: calculate or not the functional area/length, in case the variable of interest is of the type "polygon"/"polyline"
+
+ # Auxiliary variables
+ self.isArea = False # True if the geometry of the variable of interest is Polygon
+ self.isLine = False # True if the geometry of the variable of interest is Polyline
+ self.isPoint = False # True if the geometry of the variable of interest is Point
+
+ self.listbuffers = '' # List of buffer map names (with input map) generated by createBuffer function
+ self.Listerased = '' # List of donut buffer map names (buffer without input mao) generated by erase function
+ self.listclip = '' # List of maps with the variable of interest clipped by donut buffer maps, generated by clip_variable_interest_by_donut_buffer function
+
+ self.list_buffer_scales = [] # List of buffer sizes (e.g., 500, 1000, 1500, 2000)
+ self.ListIDcod = [] # List of ID codes - features of the input map, around which buffers will be drawn
+ self.FieldList = [] # List of column names in a shapefile, used for checking if a given column exists
+ self.referenceListquery = [] # List of queries: SQL expressions used to select each feature of the input map
+ self.listDonutMapAreas = [] # List of total areas of Donut maps (buffer without the input map feature)
+ self.countList = [] # List of number of features inside the donut buffer maps, for each buffer size
+ self.listAreaInsideBuffer = [] # List of area of polygons of the variable of interest that overlap the donut buffer maps, for each buffer size
+ self.listFunctionalArea = [] # List of functional area of polygons that overlap the donut buffer maps, for each buffer size
+ self.listLengthInsideBuffer = [] # List of length of polylines of the variable of interest that overlap the donut buffer maps, for each buffer size
+ self.listFunctionalLength = [] # List of functional length of lines that overlap the donut buffer maps, for each buffer size
+
+ self.counter = 0 # Counter to identify the elements of the polygon ID list
+ self.onelist = '' # Global Class List to be used by the function selectINlist
+ self.pattern = '' # Global Class pattern string to be used by the function selectINlist
+
+ #self.feature=feature_to_count # = variable of interest, i.e, the shapefile whose features should be counted
+
+ # Output files and names
+ self.txtArea = '' # Output file where area analysis will be saved
+ self.txtFuncArea = '' # Output file where functional area analysis will be saved
+ self.txtLength = '' # Output file where length analysis will be saved
+ self.txtFuncLength = '' # Output file where functional length analysis will be saved
+ self.txtCountFeat = '' # Output file where cont feature analysis will be saved
+ self.txtBufferArea = '' # Output file where donut buffer areas will be saved
+
+ # Names of the output files
+ # Area
+ self.txtArea_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Area.txt"
+ # Functional area
+ self.txtFuncArea_name = self.OutPutTxt+"_"+self.variable_interest_name+"_FunctionalArea.txt"
+ # Length
+ self.txtLength_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Length.txt"
+ # Functional length
+ self.txtFuncLength_name = self.OutPutTxt+"_"+self.variable_interest_name+"_FunctionalLength.txt"
+ # Count feaures
+ self.txtCountFeat_name = self.OutPutTxt+"_"+self.variable_interest_name+"_Count.txt"
+ # Donut buffer area
+ self.txtBufferArea_name = self.OutPutTxt+"_"+self.variable_interest_name+'_BufferArea.txt'
+
+ # Defining the workspace for ArcGIS as the output folder
+ arcpy.env.workspace=self.OutPutFolder
+
+ #------------------------
+ def defineScale(self):
+ '''
+ Function defineScale
+
+ This function reads the parameters scale (buffer size) and number of buffers
+ and defines a list of buffer sizes.
+ '''
+
+ # Assess the minimum buffer size
+ con_esc=self.scale
+
+ # For each element up to the number of buffers
+ for i in range(self.nbuffers):
+ self.list_buffer_scales.append(con_esc) # Appending a buffer value to the buffer scale list
+ con_esc=con_esc+self.scale # Defining the next buffer value
+
+
+ def createInputMapIDList(self):
+ '''
+ Function createInputMapIDList
+
+ This function creates a list of features (ID, names, ...) given the input map
+ and the identificator column.
+ Each component of this list corresponds to a feature of the input map.
+ '''
+
+ # Looking at the elements of the inputCol, within the inputmap
+ with arcpy.da.SearchCursor(self.inputmap, self.inputCol) as cursor:
+ for row in cursor:
+ # Tries to transform the elements in interger numbers, in case numerical IDs are used
+ try:
+ temp=int(row[0])
+ self.ListIDcod.append(temp) # Appends the value to the list of ID codes
+ query="\""+self.inputCol+"\"="+`temp` # Creating SQL expression for retrieving this feature later on
+ # If it is not possible, it considers the elements of the column as strings
+ except:
+ self.ListIDcod.append(row[0]) # Appends the value to the list of ID codes
+ query = self.inputCol+"='%s'" % row[0] # Creating SQL expression for retrieving this feature later on
+
+ self.referenceListquery.append(query) # Appending expression to query list
+
+
+ # This function deletes pre-existing shape files in the output geodatabase
+ def deleteFiles(self):
+ '''
+ Function deleteFiles
+
+ This function deletes pre-existing shape files in the output geodatabase.
+ '''
+
+ # If the geodatabase exists in the output folder
+ if os.path.exists(self.OutPutFolder+'/'+geoDB_name):
+ # Sets the ArcGIS workspace as the geodatabase
+ arcpy.env.workspace=self.OutPutFolder+'/'+geoDB_name
+ # Raises a list of shape features in the geodatabase
+ onelist=arcpy.ListFeatureClasses()
+ # For each element in the list, deletes the feature and the shapefile
+ for i in onelist:
+ inp = i.replace(".shp", '')
+ arcpy.Delete_management(i)
+ arcpy.Delete_management(inp)
+
+
+ def selectInList(self):
+ '''
+ Function selectInList
+
+ This function looks into a list (self.onelist), search for elements that match the
+ string self.pattern, and returns the list of matched elements.
+ '''
+
+ # Initializing list
+ onelist=[]
+ # For each element in a list of shapefile names
+ for i in self.onelist:
+ # If the string pattern is found inside the name
+ if self.pattern in i:
+ onelist.append(i) # Appends that to the list
+
+ return onelist # Returns the list of matched elements
+
+
+ def createDb(self):
+ '''
+ Function createDb
+
+ In case the geodatabase for saving the maps does not exist, this function creates it.
+ '''
+
+ # If the geodatabase does not exist
+ if not os.path.exists(self.OutPutFolder+'/'+geoDB_name):
+ arcpy.CreateFileGDB_management(self.OutPutFolder, geoDB_name) # Create it
+
+
+ def createBuffer(self):
+ '''
+ Function createBuffer
+
+ This function generates buffer maps (which overlap the input map).
+ It also defines a list of buffer map names called self.listbuffers.
+ '''
+
+ # Defining the geodatabase, inside the output folder, as the ArcGIS workspace
+ arcpy.env.workspace=self.OutPutFolder+'/'+geoDB_name
+
+ # Polygon ID info, for saving it in the buffer map name
+ idcod = str(self.ListIDcod[self.counter])
+
+ # For each buffer size in the list of buffer scales:
+ for i in self.list_buffer_scales:
+ # Format buffer size in the map name
+ formatName="00000"+`i`
+ formatName=formatName[-5:] # MAXIMUM BUFFER SIZE = 99999
+ # Define the output buffer map name
+ OutPutName=self.inputmap_name+"_ID_"+idcod+"_buffer_with_inputmap_"+formatName
+ # Create buffer shapefile, with the original polygon together
+ arcpy.Buffer_analysis(self.inputmap, OutPutName, i, "FULL", "FLAT", "ALL")
+
+ # List features in the geodatabase, searches for the buffer ones just created,
+ # and saves these names in a list called self.listbuffers
+ listbuffers = arcpy.ListFeatureClasses()
+ self.onelist = listbuffers
+ self.pattern = idcod+"_buffer_with_inputmap_" # Pattern to be found in the map names
+ self.listbuffers=MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of buffer map names
+
+
+ def erase(self):
+ '''
+ Function erase
+
+ This function erases the original input feature from the buffer map,
+ resulting in a donut-like buffer.
+ It also defines a list of donut buffer map names called self.Listerased,
+ and a list of donut buffer map areas called self.listDonutMapAreas.
+ '''
+
+ # Polygon ID info, for saving it in the buffer map name
+ idcod = str(self.ListIDcod[self.counter])
+
+ # For each map in the list of buffer map names
+ for i in self.listbuffers:
+ # Define the name of the donut map, replacing "buffer" by "donut"
+ out_name=i.replace("buffer_with_inputmap", "donut_buffer")
+ # Erases the input map from the buffer map and produces a donut map
+ arcpy.Erase_analysis(i, self.inputmap, out_name, '')
+
+ # Add a field to the donut map attribute table, called "area_ha"
+ arcpy.AddField_management(out_name, "area_ha", "DOUBLE", 10, 10)
+ # Calculate the area of the donut, in hectares
+ arcpy.CalculateField_management(out_name, "area_ha", "!shape.area@hectares!","PYTHON_9.3","#")
+
+ # Assess the donut buffer map areas and append it to the list self.listDonutMapAreas
+ rows = arcpy.da.SearchCursor(out_name, "area_ha")
+ for row in rows:
+ self.listDonutMapAreas.append(row[0])
+ #self.lista_erases.append(out_name)
+
+ # List features in the geodatabase, searches for the donut buffer ones just created,
+ # and saves these names in a list called self.Listerased
+ Listerased = arcpy.ListFeatureClasses()
+ self.onelist = Listerased
+ self.pattern = idcod+"_donut_buffer_" # Pattern to be found in the map names
+ self.Listerased = MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of donut buffer map names
+
+
+ def typeFeature(self):
+ '''
+ Function typeFeature
+
+ This function checks the geometry type of the variable of interest (Polygon, Point) (pode Polyline ou outros????).
+ This is written in a global variable (self.isArea or self.isPoint).
+ PORQUE ELE CALCULA A AREA EM HA DE CADA POLIGONO DO MAPA DA VARIAVEL DE INTERESSE TODO?
+ EH para definir a area funcional depois?
+ '''
+
+ # Get description of the variable of interest map
+ desc = arcpy.Describe(self.variable_interest)
+ # Look at the geometry type of the map (polygons, lines, points)
+ geometryType = desc.shapeType
+
+ # If the geometryType is Polygon:
+ if geometryType == 'Polygon':
+ self.isPoint = False # Variable type is not Point
+ self.isLine = False # Variable type is not Line
+ self.isArea = True # Defines the variable type as Area
+
+ # If the Functional Area is to be calculated, calculate the area of the polygons of the variable of interest map
+ if self.func_area_length_on_off:
+ try:
+ # Add field "area_ha" to the variable of interest map
+ arcpy.AddField_management(self.variable_interest, "area_ha", "DOUBLE", 10, 10)
+ # Calculate the area of the features within the map variable of interest, in hectares
+ arcpy.CalculateField_management(self.variable_interest, "area_ha", "!shape.area@hectares!","PYTHON_9.3","#")
+
+ #arcpy.CalculateField_management(self.variable_interest, "area_ha", "!shape.area@squaremeters!","PYTHON_9.3","#")
+ #expression="!Area_ha!/10000" # Area_ha ou area_ha?
+ #arcpy.CalculateField_management(self.variable_interest,"area_ha",expression,"PYTHON_9.3","#")
+ except Exception as e:
+ pass
+
+ # If the geometryType is Polygon:
+ elif geometryType == 'Point' or geometryType == 'Multipoint':
+ self.isArea = False # Variable type is not Area
+ self.isLine = False # Variable type is not Line
+ self.isPoint = True # Defines the variable as Point
+ elif geometryType == 'Polyline':
+ self.isArea = False # Variable type is not Area
+ self.isPoint = False # Variable type is not Point
self.isLine = True # Defines the variable as Line
# If the Functional Lenth is to be calculated, calculate the length of the lines of the variable of interest map
@@ -389,451 +389,451 @@ class MSBuffer(object):
# Calculate the length of the features within the map variable of interest, in meters
arcpy.CalculateField_management(self.variable_interest, "length_m", "!shape.length@meters!","PYTHON_9.3","#")
except Exception as e:
- pass
-
-
- def countFeatures(self):
- '''
- Function countFeatures
-
- This function counts the number of features that intersect with the donut buffer map, for each
- buffer size. It stores the value of the number of features in the list self.countList, a list of
- number of features for each buffer size.
- '''
-
- # For each map in the list of donut buffer maps:
- for donut in self.Listerased:
- # Select the features in the variable of interest map that intersects with the donut buffer
- arcpy.SelectLayerByLocation_management(self.variable_interest, "INTERSECT", donut)
- # Looks at each feature selected
- cursor = arcpy.da.SearchCursor(self.variable_interest, ['FID'])
-
- # Counts the number of features in the variable "count"
- #count = 0
- #for i in cursor:
- #count = count+1
- list_cursor = list(cursor)
- count = len(list_cursor)
-
- # Appends the number of features to the list self.countList
- self.countList.append(count)
-
-
- def calcFunctionalArea_Length(self):
- '''
- Function calcFunctionalArea_Length
-
- This function calculates the functional area (for polygons) or length (for lines) of the variable of interest,
- for all buffer sizes. The values for each buffer size is saved in the list self.listFunctionalArea (for polygons)
- or self.listFunctionalLength (for lines).
-
- Details: the function checks the features of the variable of interest that overlaps the donut buffer map,
- and sum the complete area/length of these features (not only the area/length iside the buffer).
- This summed area/length is here called functional area/length.
- '''
-
- # For each map in the donut buffer list:
- for donut in self.Listerased:
- # Select the features in the variable of interest map that intersects with the donut buffer
- arcpy.SelectLayerByLocation_management(self.variable_interest, "INTERSECT", donut) # para calcular functional area??????????????
-
- # If the map is an Area map, calculate functional area
- if self.isArea == True:
- # Retrieving the area (in hectares) of each selected feature
- with arcpy.da.SearchCursor(self.variable_interest, "area_ha") as cursor:
- # Initializing the total area
- summed_total=0
- # For each polygon area
- for row in cursor:
- summed_total = summed_total + row[0] # Sum the polygon area to the total area
- summed_total = round(summed_total, ndigits=2) # Round the total area to 2 digits
- self.listFunctionalArea.append(summed_total) # Appends the total functional area to the list of functional areas for each buffer size
-
- # If the map is a Line map, calculate functional length
- elif self.isLine == True:
- # Retrieving the length (in meters) of each selected feature
- with arcpy.da.SearchCursor(self.variable_interest, "length_m") as cursor:
- # Initializing the total length
- summed_total=0
- # For each line length
- for row in cursor:
- summed_total = summed_total + row[0] # Sum the line length to the total length
- summed_total = round(summed_total, ndigits=2) # Round the total area to 2 digits
- self.listFunctionalLength.append(summed_total) # Appends the total functional length to the list of functional lengths for each buffer size
-
-
- def clip_variable_interest_by_donut_buffer(self):
- '''
- Function clip_variable_interest_by_donut_buffer
-
- This function clips the map of the variable of interest inside the donut buffer area.
- It also defines a list of names of variable of interest map inside the donut buffers, called self.listclip
- '''
-
- # Polygon ID info, for saving it in the buffer map name
- idcod = str(self.ListIDcod[self.counter])
-
- # For each donut buffer map:
- for i in self.Listerased:
- # Define the name of the clip map
- out_name = i.replace("donut_buffer", self.variable_interest_name+"_inside_donut_buffer")
- # Clips the variable of interest map features inside the donut buffer map
- arcpy.Clip_analysis(self.variable_interest, i, out_name, "")
-
- # List features in the geodatabase, searches for the CLIP ones just created,
- # and saves these names in a list called self.listclip
- Listclip = arcpy.ListFeatureClasses()
- self.onelist = Listclip
- self.pattern = idcod+"_"+self.variable_interest_name+"_inside_donut_buffer_" # Pattern to be found in the map names
- self.listclip = MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of CLIP map names
-
-
- def checkField(self, shape_map):
- '''
- Function checkField
-
- This function returns a list of fields (columns) of an attribute table of a shapefile map.
- The list is also recorded as a class global variable, named self.FieldList.
- '''
-
- # List the fields in the shapefile map
- fields = arcpy.ListFields(shape_map)
-
- # For each field, append it to a list of map columns called self.FieldList
- for field in fields:
- self.FieldList.append(field.name)
- # Returns the list
- return self.FieldList
-
-
- def deleteField(self):
- '''
- Function deleteField
-
- This function deletes the field "Area_ha" from the clip map (the areas of features inside the donut buffer)
- '''
-
- # For each CLIP map:
- for i in self.listclip:
- # Lists the fields/columns in the attribute table of the map
- fields = MSBuffer.checkField(self, i)
- # If there is a column called "Area_ha":
- if "Area_clip_ha" in fields:
- arcpy.DeleteField_management(i, ["Area_clip_ha"]) # Delete this column
-
-
- def addField(self):
- '''
- Function addField
-
- This function calculates the area (in hectares) of each feature of the clip map (i.e. the features
- of the variable of interest inside the donut buffer map) and adds this value to
- the attribute table field "Area_ha" inside the clip map
-
- # change to implement length calculation
- '''
-
- # For each CLIP map
- for i in self.listclip:
- try:
- # Add a field to the attribute table, called "Area_ha"
- arcpy.AddField_management(i, "Area_clip_ha", "DOUBLE", 10, 10)
- # Calculates the area of each feature, in hectares
- arcpy.CalculateField_management(i,"Area_clip_ha","!shape.area@hectares!","PYTHON_9.3","#")
-
- #arcpy.CalculateField_management(i,"Area_ha","!shape.area@squaremeters!","PYTHON_9.3","#")
- #expression="!Area_ha!/10000"
- #arcpy.CalculateField_management(i,"Area_ha",expression,"PYTHON_9.3","#")
- except:
- print "pass"
-
-
- def calculateArea_LengthInsideBuffer(self):
- '''
- Function calculateArea_LengthInsideBuffer
-
- This function retrieves the values of the feature areas (in case of polygons) or
- lengths (in case of polylines) of the variable of interest inside the donut buffer,
- sums it and writes it into the list self.listAreaInsideBuffer (polygons) or self.listLengthInsideBuffer (Lines).
- It works only for Polygon and Polyline shapefiles.
- '''
-
- # For each CLIP map:
- for i in self.listclip:
- # Initializes the total area of the variable of interest inside the donut buffer
- summed_total = 0
-
- # If the map geometry is polygon:
- if self.isArea:
- # For each polygon in the CLIP map:
- with arcpy.da.SearchCursor(i, "Shape_Area") as cursor: # Uses the "Shape_Area" column, created when the clip map is created
- #with arcpy.da.SearchCursor(i, "Area_clip_ha") as cursor: # This is in the case of calculating the area of each polygon
- # Sum the polygon area of the variable of interest to the total area
- for row in cursor:
- summed_total = summed_total + row[0]
- summed_total = summed_total/10000 # This calculation is based on the "Shape_Area" column; if "Area_clip_ha" is used, this must be removed.
- summed_total = round(summed_total, ndigits = 2) # Rounds the value to two digits
- self.listAreaInsideBuffer.append(summed_total) # Appends it to the list of areas inside the donut buffer
-
- # If the map geometry is polyline:
- elif self.isLine:
- # For each line in the CLIP map:
- with arcpy.da.SearchCursor(i, "Shape_Length") as cursor: # Uses the "Shape_Length" column, created when the clip map is created
- # Sum the line length of the variable of interest to the total length
- for row in cursor:
- summed_total = summed_total + row[0]
- #summed_total = summed_total/1000 # For kilometers, not used
- summed_total = round(summed_total, ndigits = 2) # Rounds the value to two digits
- self.listLengthInsideBuffer.append(summed_total) # Appends it to the list of lengths inside the donut buffer
-
-
- def removeDuplicateList(self, onelist):
- '''
- Function removeDuplicateList
-
- Remove duplicated items inside a list, and returns a list without duplications.
- '''
-
- # Creating list without duplications
- onelistapoio=[]
-
- # For each element in the input list
- for i in onelist:
- # If this element is not already in the list without duplication
- if not i in onelistapoio:
- onelistapoio.append(i) # Append that to the list without duplication
-
- return onelistapoio # Returns list without duplication
-
-
- def initializeOutputTxt(self):
- '''
- Function initializeOutputTxt
-
- This function initializes (creates) the text outputs and write the header on them.
- '''
-
- # Area
- if self.isArea and self.area_length_on_off:
- self.txtArea = open(self.txtArea_name, 'w')
- self.txtArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtArea.write('\n')
- self.txtArea.close()
-
- # Functional area
- if self.isArea and self.func_area_length_on_off:
- self.txtFuncArea = open(self.txtFuncArea_name, 'w')
- self.txtFuncArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtFuncArea.write('\n')
- self.txtFuncArea.close()
-
- # Length
- if self.isLine and self.area_length_on_off:
- self.txtLength = open(self.txtLength_name, 'w')
- self.txtLength.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtLength.write('\n')
- self.txtLength.close()
-
- # Functional area
- if self.isLine and self.func_area_length_on_off:
- self.txtFuncLength = open(self.txtFuncLength_name, 'w')
- self.txtFuncLength.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtFuncLength.write('\n')
- self.txtFuncLength.close()
-
- # Count feaures
- if self.count_on_off:
- self.txtCountFeat = open(self.txtCountFeat_name, 'w')
- self.txtCountFeat.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtCountFeat.write('\n')
- self.txtCountFeat.close()
-
- # Buffer area
- self.txtBufferArea = open(self.txtBufferArea_name, 'w')
- self.txtBufferArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
- self.txtBufferArea.write('\n')
- self.txtBufferArea.close()
-
-
- def createOutputTxt(self):
- '''
- function createOutputTxt
-
- This function writes output information in the output text files.
- The number and type of outputs depend on the users choice parameters.
- '''
-
- # Polygon ID info
- idcod = str(self.ListIDcod[self.counter])
-
- # AREA INSIDE BUFFER
- # Appends one line (one feature of the input map) with the Area inside the Buffer to the output text file
- #self.listAreaInsideBuffer=MSBuffer.removeDuplicateList(self, self.listAreaInsideBuffer)
- if self.isArea and self.area_length_on_off:
- self.txtArea = open(self.txtArea_name, 'a')
- self.txtArea.write(idcod+','+','.join(str(x) for x in self.listAreaInsideBuffer))
- self.txtArea.write('\n')
- self.txtArea.close()
- self.listAreaInsideBuffer = []
-
- # FUNCTIONAL AREA
- # Appends one line (one feature of the input map) with the Functional Area to the output text file
- if self.isArea and self.func_area_length_on_off:
- self.listFunctionalArea = MSBuffer.removeDuplicateList(self, self.listFunctionalArea)
- self.txtFuncArea = open(self.txtFuncArea_name, 'a')
- self.txtFuncArea.write(idcod+','+','.join(str(x) for x in self.listFunctionalArea))
- self.txtFuncArea.write('\n')
- self.txtFuncArea.close()
- self.listFunctionalArea = []
-
- # LENGTH INSIDE BUFFER
- # Appends one line (one feature of the input map) with the Length inside the Buffer to the output text file
- #self.listAreaInsideBuffer=MSBuffer.removeDuplicateList(self, self.listAreaInsideBuffer)
- if self.isLine and self.area_length_on_off:
- self.txtLength = open(self.txtLength_name, 'a')
- self.txtLength.write(idcod+','+','.join(str(x) for x in self.listLengthInsideBuffer))
- self.txtLength.write('\n')
- self.txtLength.close()
- self.listLengthInsideBuffer = []
-
- # FUNCTIONAL AREA
- # Appends one line (one feature of the input map) with the Functional Area to the output text file
- if self.isLine and self.func_area_length_on_off:
- self.listFunctionalLength = MSBuffer.removeDuplicateList(self, self.listFunctionalLength)
- self.txtFuncLength = open(self.txtFuncLength_name, 'a')
- self.txtFuncLength.write(idcod+','+','.join(str(x) for x in self.listFunctionalLength))
- self.txtFuncLength.write('\n')
- self.txtFuncLength.close()
- self.listFunctionalLength = []
-
- # COUNT FEATURES
- # Appends one line (one feature of the input map) with the count of features inside the donut buffer
- # to the output text file
- if self.count_on_off:
- #self.countList = MSBuffer.removeDuplicateList(self, self.countList)
- self.txtCountFeat = open(self.txtCountFeat_name, 'a')
- self.txtCountFeat.write(idcod+','+','.join(str(x) for x in self.countList))
- self.txtCountFeat.write('\n')
- self.txtCountFeat.close()
- self.countList = []
-
- # BUFFER AREAS
- self.txtBufferArea = open(self.txtBufferArea_name, 'a')
- self.txtBufferArea.write(idcod+','+','.join(str(x) for x in self.listDonutMapAreas)) # File header
- self.txtBufferArea.write('\n')
- self.txtBufferArea.close()
- self.listDonutMapAreas = []
-
-
-#----------------------------------------------------------------------------------
-# The Run class calls MSBuffer functions in order to perform the Multi-Scale buffer analysis
-# It inherits the MSBuffer class
-
-class Run(MSBuffer):
-
- # Initializing parameters
- def __init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
- scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off):
-
- if not (count_on_off or area_length_on_off or func_area_length_on_off):
- string_error = "At least one of the options must be selected:\n" + \
- "Count Features\nCalculate Area/Length\nCalculate Functional Area/Length\n\n" + \
- "Please, select one of them and try again!"
-
- raise Exception(string_error)
-
-
- MSBuffer.__init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
- scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off)
-
- # Clear selection of features
- arcpy.SelectLayerByAttribute_management(self.inputmap, "CLEAR_SELECTION")
-
- def run(self):
- '''
- Function run
-
- In this function the analysis is performed.
- '''
-
- #----------
- # Preparing
-
- # Define the geometry of the variable of interest
- MSBuffer.typeFeature(self)
- # Create the list of polygon IDs, from the input map
- MSBuffer.createInputMapIDList(self)
- # Define the list of buffer sizes
- MSBuffer.defineScale(self)
- # If the Geodatabase does not exist, creates it
- MSBuffer.createDb(self)
-
- #---------
- # Analyses
-
- # Change to output folder
- os.chdir(OutPutFolder)
-
- # Initialize output text file for area analysis
- MSBuffer.initializeOutputTxt(self)
-
- # If the maps will be saved, the previous maps inside the geodatabase may be deleted
- # Delete previous files from the geodatabase, to perform new analysis
- if overwrite_maps == True:
- MSBuffer.deleteFiles(self)
-
- # Initializing counter for getting polygon ID from the input map (around which buffers are drawn)
- self.counter = 0
-
- # For each feature in the input map:
- for i in self.referenceListquery:
-
- # Select the feature from the input map
- arcpy.SelectLayerByAttribute_management(self.inputmap, "NEW_SELECTION", i)
- # Create Buffer (with the feature embedded)
- MSBuffer.createBuffer(self)
- # Erase the input map feature from the buffer, generating a donut buffer
- MSBuffer.erase(self)
-
- # Count features
- if self.count_on_off:
- MSBuffer.countFeatures(self)
- # Calculate Functional Area
- if (self.isArea or self.isLine) and self.func_area_length_on_off:
- MSBuffer.calcFunctionalArea_Length(self)
-
- # Calculate Area
- if (self.isArea or self.isLine) and self.area_length_on_off:
- MSBuffer.clip_variable_interest_by_donut_buffer(self)
- # The functions deleteField and addField, which delete the area column and recalculates it, are not being used,
- # since the area of polygons of the variable of interest inside the donut buffer are calculated through the "Shape_Area" column,
- # created automatically when the clip map is created.
- # However, the implementation may change, if needed. We keep the functions declared in case it is necessary
- #MSBuffer.deleteField(self)
- #MSBuffer.addField(self)
- MSBuffer.calculateArea_LengthInsideBuffer(self)
-
- # Write outputs
- MSBuffer.createOutputTxt(self)
-
- # Next input map feature
- self.counter = self.counter + 1
-
-
- # Clear selection
- arcpy.SelectLayerByAttribute_management(self.inputmap, "CLEAR_SELECTION")
-
- # If the maps will not be saved, delete them
- if not self.save_maps:
- ## Delete files from the geodatabase
- MSBuffer.deleteFiles(self)
-
-
-#----------------------------------------------------------------------------------
-# Running the analysis
-
-# Run instance
-run_instance = Run(inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
- scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off)
-# Run
-run_instance.run()
+ pass
+
+
+ def countFeatures(self):
+ '''
+ Function countFeatures
+
+ This function counts the number of features that intersect with the donut buffer map, for each
+ buffer size. It stores the value of the number of features in the list self.countList, a list of
+ number of features for each buffer size.
+ '''
+
+ # For each map in the list of donut buffer maps:
+ for donut in self.Listerased:
+ # Select the features in the variable of interest map that intersects with the donut buffer
+ arcpy.SelectLayerByLocation_management(self.variable_interest, "INTERSECT", donut)
+ # Looks at each feature selected
+ cursor = arcpy.da.SearchCursor(self.variable_interest, ['FID'])
+
+ # Counts the number of features in the variable "count"
+ #count = 0
+ #for i in cursor:
+ #count = count+1
+ list_cursor = list(cursor)
+ count = len(list_cursor)
+
+ # Appends the number of features to the list self.countList
+ self.countList.append(count)
+
+
+ def calcFunctionalArea_Length(self):
+ '''
+ Function calcFunctionalArea_Length
+
+ This function calculates the functional area (for polygons) or length (for lines) of the variable of interest,
+ for all buffer sizes. The values for each buffer size is saved in the list self.listFunctionalArea (for polygons)
+ or self.listFunctionalLength (for lines).
+
+ Details: the function checks the features of the variable of interest that overlaps the donut buffer map,
+ and sum the complete area/length of these features (not only the area/length iside the buffer).
+ This summed area/length is here called functional area/length.
+ '''
+
+ # For each map in the donut buffer list:
+ for donut in self.Listerased:
+ # Select the features in the variable of interest map that intersects with the donut buffer
+ arcpy.SelectLayerByLocation_management(self.variable_interest, "INTERSECT", donut) # para calcular functional area??????????????
+
+ # If the map is an Area map, calculate functional area
+ if self.isArea == True:
+ # Retrieving the area (in hectares) of each selected feature
+ with arcpy.da.SearchCursor(self.variable_interest, "area_ha") as cursor:
+ # Initializing the total area
+ summed_total=0
+ # For each polygon area
+ for row in cursor:
+ summed_total = summed_total + row[0] # Sum the polygon area to the total area
+ summed_total = round(summed_total, ndigits=2) # Round the total area to 2 digits
+ self.listFunctionalArea.append(summed_total) # Appends the total functional area to the list of functional areas for each buffer size
+
+ # If the map is a Line map, calculate functional length
+ elif self.isLine == True:
+ # Retrieving the length (in meters) of each selected feature
+ with arcpy.da.SearchCursor(self.variable_interest, "length_m") as cursor:
+ # Initializing the total length
+ summed_total=0
+ # For each line length
+ for row in cursor:
+ summed_total = summed_total + row[0] # Sum the line length to the total length
+ summed_total = round(summed_total, ndigits=2) # Round the total area to 2 digits
+ self.listFunctionalLength.append(summed_total) # Appends the total functional length to the list of functional lengths for each buffer size
+
+
+ def clip_variable_interest_by_donut_buffer(self):
+ '''
+ Function clip_variable_interest_by_donut_buffer
+
+ This function clips the map of the variable of interest inside the donut buffer area.
+ It also defines a list of names of variable of interest map inside the donut buffers, called self.listclip
+ '''
+
+ # Polygon ID info, for saving it in the buffer map name
+ idcod = str(self.ListIDcod[self.counter])
+
+ # For each donut buffer map:
+ for i in self.Listerased:
+ # Define the name of the clip map
+ out_name = i.replace("donut_buffer", self.variable_interest_name+"_inside_donut_buffer")
+ # Clips the variable of interest map features inside the donut buffer map
+ arcpy.Clip_analysis(self.variable_interest, i, out_name, "")
+
+ # List features in the geodatabase, searches for the CLIP ones just created,
+ # and saves these names in a list called self.listclip
+ Listclip = arcpy.ListFeatureClasses()
+ self.onelist = Listclip
+ self.pattern = idcod+"_"+self.variable_interest_name+"_inside_donut_buffer_" # Pattern to be found in the map names
+ self.listclip = MSBuffer.selectInList(self) # Searching for the pattern in map names and defining the list of CLIP map names
+
+
+ def checkField(self, shape_map):
+ '''
+ Function checkField
+
+ This function returns a list of fields (columns) of an attribute table of a shapefile map.
+ The list is also recorded as a class global variable, named self.FieldList.
+ '''
+
+ # List the fields in the shapefile map
+ fields = arcpy.ListFields(shape_map)
+
+ # For each field, append it to a list of map columns called self.FieldList
+ for field in fields:
+ self.FieldList.append(field.name)
+ # Returns the list
+ return self.FieldList
+
+
+ def deleteField(self):
+ '''
+ Function deleteField
+
+ This function deletes the field "Area_ha" from the clip map (the areas of features inside the donut buffer)
+ '''
+
+ # For each CLIP map:
+ for i in self.listclip:
+ # Lists the fields/columns in the attribute table of the map
+ fields = MSBuffer.checkField(self, i)
+ # If there is a column called "Area_ha":
+ if "Area_clip_ha" in fields:
+ arcpy.DeleteField_management(i, ["Area_clip_ha"]) # Delete this column
+
+
+ def addField(self):
+ '''
+ Function addField
+
+ This function calculates the area (in hectares) of each feature of the clip map (i.e. the features
+ of the variable of interest inside the donut buffer map) and adds this value to
+ the attribute table field "Area_ha" inside the clip map
+
+ # change to implement length calculation
+ '''
+
+ # For each CLIP map
+ for i in self.listclip:
+ try:
+ # Add a field to the attribute table, called "Area_ha"
+ arcpy.AddField_management(i, "Area_clip_ha", "DOUBLE", 10, 10)
+ # Calculates the area of each feature, in hectares
+ arcpy.CalculateField_management(i,"Area_clip_ha","!shape.area@hectares!","PYTHON_9.3","#")
+
+ #arcpy.CalculateField_management(i,"Area_ha","!shape.area@squaremeters!","PYTHON_9.3","#")
+ #expression="!Area_ha!/10000"
+ #arcpy.CalculateField_management(i,"Area_ha",expression,"PYTHON_9.3","#")
+ except:
+ print "pass"
+
+
+ def calculateArea_LengthInsideBuffer(self):
+ '''
+ Function calculateArea_LengthInsideBuffer
+
+ This function retrieves the values of the feature areas (in case of polygons) or
+ lengths (in case of polylines) of the variable of interest inside the donut buffer,
+ sums it and writes it into the list self.listAreaInsideBuffer (polygons) or self.listLengthInsideBuffer (Lines).
+ It works only for Polygon and Polyline shapefiles.
+ '''
+
+ # For each CLIP map:
+ for i in self.listclip:
+ # Initializes the total area of the variable of interest inside the donut buffer
+ summed_total = 0
+
+ # If the map geometry is polygon:
+ if self.isArea:
+ # For each polygon in the CLIP map:
+ with arcpy.da.SearchCursor(i, "Shape_Area") as cursor: # Uses the "Shape_Area" column, created when the clip map is created
+ #with arcpy.da.SearchCursor(i, "Area_clip_ha") as cursor: # This is in the case of calculating the area of each polygon
+ # Sum the polygon area of the variable of interest to the total area
+ for row in cursor:
+ summed_total = summed_total + row[0]
+ summed_total = summed_total/10000 # This calculation is based on the "Shape_Area" column; if "Area_clip_ha" is used, this must be removed.
+ summed_total = round(summed_total, ndigits = 2) # Rounds the value to two digits
+ self.listAreaInsideBuffer.append(summed_total) # Appends it to the list of areas inside the donut buffer
+
+ # If the map geometry is polyline:
+ elif self.isLine:
+ # For each line in the CLIP map:
+ with arcpy.da.SearchCursor(i, "Shape_Length") as cursor: # Uses the "Shape_Length" column, created when the clip map is created
+ # Sum the line length of the variable of interest to the total length
+ for row in cursor:
+ summed_total = summed_total + row[0]
+ #summed_total = summed_total/1000 # For kilometers, not used
+ summed_total = round(summed_total, ndigits = 2) # Rounds the value to two digits
+ self.listLengthInsideBuffer.append(summed_total) # Appends it to the list of lengths inside the donut buffer
+
+
+ def removeDuplicateList(self, onelist):
+ '''
+ Function removeDuplicateList
+
+ Remove duplicated items inside a list, and returns a list without duplications.
+ '''
+
+ # Creating list without duplications
+ onelistapoio=[]
+
+ # For each element in the input list
+ for i in onelist:
+ # If this element is not already in the list without duplication
+ if not i in onelistapoio:
+ onelistapoio.append(i) # Append that to the list without duplication
+
+ return onelistapoio # Returns list without duplication
+
+
+ def initializeOutputTxt(self):
+ '''
+ Function initializeOutputTxt
+
+ This function initializes (creates) the text outputs and write the header on them.
+ '''
+
+ # Area
+ if self.isArea and self.area_length_on_off:
+ self.txtArea = open(self.txtArea_name, 'w')
+ self.txtArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtArea.write('\n')
+ self.txtArea.close()
+
+ # Functional area
+ if self.isArea and self.func_area_length_on_off:
+ self.txtFuncArea = open(self.txtFuncArea_name, 'w')
+ self.txtFuncArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtFuncArea.write('\n')
+ self.txtFuncArea.close()
+
+ # Length
+ if self.isLine and self.area_length_on_off:
+ self.txtLength = open(self.txtLength_name, 'w')
+ self.txtLength.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtLength.write('\n')
+ self.txtLength.close()
+
+ # Functional area
+ if self.isLine and self.func_area_length_on_off:
+ self.txtFuncLength = open(self.txtFuncLength_name, 'w')
+ self.txtFuncLength.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtFuncLength.write('\n')
+ self.txtFuncLength.close()
+
+ # Count feaures
+ if self.count_on_off:
+ self.txtCountFeat = open(self.txtCountFeat_name, 'w')
+ self.txtCountFeat.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtCountFeat.write('\n')
+ self.txtCountFeat.close()
+
+ # Buffer area
+ self.txtBufferArea = open(self.txtBufferArea_name, 'w')
+ self.txtBufferArea.write(self.inputCol+','+','.join(str(x) for x in self.list_buffer_scales)) # File header
+ self.txtBufferArea.write('\n')
+ self.txtBufferArea.close()
+
+
+ def createOutputTxt(self):
+ '''
+ function createOutputTxt
+
+ This function writes output information in the output text files.
+ The number and type of outputs depend on the users choice parameters.
+ '''
+
+ # Polygon ID info
+ idcod = str(self.ListIDcod[self.counter])
+
+ # AREA INSIDE BUFFER
+ # Appends one line (one feature of the input map) with the Area inside the Buffer to the output text file
+ #self.listAreaInsideBuffer=MSBuffer.removeDuplicateList(self, self.listAreaInsideBuffer)
+ if self.isArea and self.area_length_on_off:
+ self.txtArea = open(self.txtArea_name, 'a')
+ self.txtArea.write(idcod+','+','.join(str(x) for x in self.listAreaInsideBuffer))
+ self.txtArea.write('\n')
+ self.txtArea.close()
+ self.listAreaInsideBuffer = []
+
+ # FUNCTIONAL AREA
+ # Appends one line (one feature of the input map) with the Functional Area to the output text file
+ if self.isArea and self.func_area_length_on_off:
+ self.listFunctionalArea = MSBuffer.removeDuplicateList(self, self.listFunctionalArea)
+ self.txtFuncArea = open(self.txtFuncArea_name, 'a')
+ self.txtFuncArea.write(idcod+','+','.join(str(x) for x in self.listFunctionalArea))
+ self.txtFuncArea.write('\n')
+ self.txtFuncArea.close()
+ self.listFunctionalArea = []
+
+ # LENGTH INSIDE BUFFER
+ # Appends one line (one feature of the input map) with the Length inside the Buffer to the output text file
+ #self.listAreaInsideBuffer=MSBuffer.removeDuplicateList(self, self.listAreaInsideBuffer)
+ if self.isLine and self.area_length_on_off:
+ self.txtLength = open(self.txtLength_name, 'a')
+ self.txtLength.write(idcod+','+','.join(str(x) for x in self.listLengthInsideBuffer))
+ self.txtLength.write('\n')
+ self.txtLength.close()
+ self.listLengthInsideBuffer = []
+
+ # FUNCTIONAL AREA
+ # Appends one line (one feature of the input map) with the Functional Area to the output text file
+ if self.isLine and self.func_area_length_on_off:
+ self.listFunctionalLength = MSBuffer.removeDuplicateList(self, self.listFunctionalLength)
+ self.txtFuncLength = open(self.txtFuncLength_name, 'a')
+ self.txtFuncLength.write(idcod+','+','.join(str(x) for x in self.listFunctionalLength))
+ self.txtFuncLength.write('\n')
+ self.txtFuncLength.close()
+ self.listFunctionalLength = []
+
+ # COUNT FEATURES
+ # Appends one line (one feature of the input map) with the count of features inside the donut buffer
+ # to the output text file
+ if self.count_on_off:
+ #self.countList = MSBuffer.removeDuplicateList(self, self.countList)
+ self.txtCountFeat = open(self.txtCountFeat_name, 'a')
+ self.txtCountFeat.write(idcod+','+','.join(str(x) for x in self.countList))
+ self.txtCountFeat.write('\n')
+ self.txtCountFeat.close()
+ self.countList = []
+
+ # BUFFER AREAS
+ self.txtBufferArea = open(self.txtBufferArea_name, 'a')
+ self.txtBufferArea.write(idcod+','+','.join(str(x) for x in self.listDonutMapAreas)) # File header
+ self.txtBufferArea.write('\n')
+ self.txtBufferArea.close()
+ self.listDonutMapAreas = []
+
+
+#----------------------------------------------------------------------------------
+# The Run class calls MSBuffer functions in order to perform the Multi-Scale buffer analysis
+# It inherits the MSBuffer class
+
+class Run(MSBuffer):
+
+ # Initializing parameters
+ def __init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
+ scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off):
+
+ if not (count_on_off or area_length_on_off or func_area_length_on_off):
+ string_error = "At least one of the options must be selected:\n" + \
+ "Count Features\nCalculate Area/Length\nCalculate Functional Area/Length\n\n" + \
+ "Please, select one of them and try again!"
+
+ raise Exception(string_error)
+
+
+ MSBuffer.__init__(self, inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
+ scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off)
+
+ # Clear selection of features
+ arcpy.SelectLayerByAttribute_management(self.inputmap, "CLEAR_SELECTION")
+
+ def run(self):
+ '''
+ Function run
+
+ In this function the analysis is performed.
+ '''
+
+ #----------
+ # Preparing
+
+ # Define the geometry of the variable of interest
+ MSBuffer.typeFeature(self)
+ # Create the list of polygon IDs, from the input map
+ MSBuffer.createInputMapIDList(self)
+ # Define the list of buffer sizes
+ MSBuffer.defineScale(self)
+ # If the Geodatabase does not exist, creates it
+ MSBuffer.createDb(self)
+
+ #---------
+ # Analyses
+
+ # Change to output folder
+ os.chdir(OutPutFolder)
+
+ # Initialize output text file for area analysis
+ MSBuffer.initializeOutputTxt(self)
+
+ # If the maps will be saved, the previous maps inside the geodatabase may be deleted
+ # Delete previous files from the geodatabase, to perform new analysis
+ if overwrite_maps == True:
+ MSBuffer.deleteFiles(self)
+
+ # Initializing counter for getting polygon ID from the input map (around which buffers are drawn)
+ self.counter = 0
+
+ # For each feature in the input map:
+ for i in self.referenceListquery:
+
+ # Select the feature from the input map
+ arcpy.SelectLayerByAttribute_management(self.inputmap, "NEW_SELECTION", i)
+ # Create Buffer (with the feature embedded)
+ MSBuffer.createBuffer(self)
+ # Erase the input map feature from the buffer, generating a donut buffer
+ MSBuffer.erase(self)
+
+ # Count features
+ if self.count_on_off:
+ MSBuffer.countFeatures(self)
+ # Calculate Functional Area
+ if (self.isArea or self.isLine) and self.func_area_length_on_off:
+ MSBuffer.calcFunctionalArea_Length(self)
+
+ # Calculate Area
+ if (self.isArea or self.isLine) and self.area_length_on_off:
+ MSBuffer.clip_variable_interest_by_donut_buffer(self)
+ # The functions deleteField and addField, which delete the area column and recalculates it, are not being used,
+ # since the area of polygons of the variable of interest inside the donut buffer are calculated through the "Shape_Area" column,
+ # created automatically when the clip map is created.
+ # However, the implementation may change, if needed. We keep the functions declared in case it is necessary
+ #MSBuffer.deleteField(self)
+ #MSBuffer.addField(self)
+ MSBuffer.calculateArea_LengthInsideBuffer(self)
+
+ # Write outputs
+ MSBuffer.createOutputTxt(self)
+
+ # Next input map feature
+ self.counter = self.counter + 1
+
+
+ # Clear selection
+ arcpy.SelectLayerByAttribute_management(self.inputmap, "CLEAR_SELECTION")
+
+ # If the maps will not be saved, delete them
+ if not self.save_maps:
+ ## Delete files from the geodatabase
+ MSBuffer.deleteFiles(self)
+
+
+#----------------------------------------------------------------------------------
+# Running the analysis
+
+# Run instance
+run_instance = Run(inputmap, inputmap_name, inputCol, variable_interest, variable_interest_name, OutPutTxt, OutPutFolder, save_maps,
+ scale, nbuffers, count_on_off, area_length_on_off, func_area_length_on_off)
+# Run
+run_instance.run()