Home Range Analysis: Best Workflow.

1022
1
04-26-2012 01:47 PM
AndrewNoonan
New Contributor
Hello friends, I am working on a project, and I am in need of some help on the best way to approach this analysis.

Background Information:
In biology, animals have home ranges, which is defined as "???that area
traversed by the individual in its normal activities of food gathering, mating, and caring for young.
Occasional sallies outside the area, perhaps exploratory in nature, should not be considered as in part of the
home range." (Burt 1943).

The Problem:
Sometimes these ranges are non-continuous, and fragmented, spanning across many different locations.

I am looking at the range of 135 specific species, and I have the range polygons for each of the species (about: 856 total).
What I need to do now is to look at [1] whether or not each of the species overlap (and all of its fragmented ranges) overlap with each of the species on the list and [2] the degree of overlap (area in km2) and [3] centroid distance (in km) between the overlap for each of the species.

The Analysis:
In essence, I will be creating a matrix (135x135) to determine whether or not they overlap. This requires consideration to all of 856 polygon ranges in all different combinations.

I have asked a friend if there was a way to do this in the ARCGIS software without writing a 4 loop repeating script (which I am not familiar with)... but he is unable to figure it out in the amount of time we had together. I am in need of suggestions of the best way to approach this.

There must be a better way to this analysis that manually using the intersection feature.

Version: ArcInfo 10.
Data Layers: One
I have all of the ranges in one shapefile with all of the ranges' polygon geocoded.
0 Kudos
1 Reply
MarcinGasior
Occasional Contributor III
I've written a script and tested on 10 species ranges for problems [1] and [2].
To make calculations easier, the input are polygon ranges consisted of many parts (mulltipart polygons).

To prepare input use Dissolve tool to dissolve data using species name field (or species id). This way one species is stored as one record.
Than create ID field of integer type. If an extent of ranges is quite large (eg. continent), project data in Equal Area projection.
Adjust patches to data and output files and run the script:
import arcpy, sys, traceback, os

workspaceDir = "C:/tmp/Test_Species.gdb"
arcpy.env.workspace = workspaceDir
speciesFC = "C:/tmp/Test_Species.gdb/Bats_EqAr_Dis"

try:
    #create unique ID for one species (make sure you have "ID" field):
    uCur = arcpy.UpdateCursor(speciesFC)
    idCount = 0
    for uRow in uCur:
        idCount += 1
        uRow.setValue("ID", idCount)
        uCur.updateRow(uRow)


#check each species geometry relation
    # create matrices to store output
    spArrayInt = [ [ 0 for x in range(idCount) ] for y in range(idCount) ]
    spArrayIntArea = [ [ 0 for x in range(idCount) ] for y in range(idCount) ]

    #loops for  first species
    for i in range(1, idCount+1):
        sCurI = arcpy.SearchCursor(speciesFC, '"ID" = ' + str(i))

        for rowI in sCurI:
            geomI = rowI.Shape #first geometry

            #loops for second species
            for j in range(1, idCount+1):
                if i > j:
                    sCurJ = arcpy.SearchCursor(speciesFC, '"ID" = ' + str(j))

                    for rowJ in sCurJ:
                        geomJ = rowJ.Shape #second geometry

                        #check if gemetries intersects
                        if geomI.overlaps(geomJ):

                            #if true, calculate intersection geometry (stored in memory) and get geometry area
                            arcpy.Intersect_analysis([geomI,geomJ], "in_memory/Intersection")
                            sCurInt = arcpy.SearchCursor("in_memory/Intersection")
                            for rowInt in sCurInt:
                                geomInt = rowInt.Shape
                                geomIntArea = int((geomInt.area)/1000000)
                            arcpy.Delete_management("in_memory/Intersection")

                            #fill matrices: 1 - geometries intersect, area - intersection area in km2
                            spArrayInt[i-1][j-1] = 1
                            spArrayInt[j-1][i-1] = 1
                            spArrayIntArea[i-1][j-1] = geomIntArea
                            spArrayIntArea[j-1][i-1] = geomIntArea

    #write output matrices to files
    outputFileInt = open("C:/tmp/Species_int.txt","w")
    for line in spArrayInt:
        lineToWrite = (", ").join(str(v) for v in line)
        outputFileInt.write(lineToWrite + "\n")
    outputFileInt.close()

    outputFileIntArea = open("C:/tmp/Species_int_area.txt","w")
    for line in spArrayIntArea:
        lineToWrite = (", ").join(str(v) for v in line)
        outputFileIntArea.write(lineToWrite + "\n")
    outputFileIntArea.close()


except:
    print arcpy.GetMessages()
    # Get the traceback object
    tb = sys.exc_info()[2]
    tbinfo = traceback.format_tb(tb)[0]

    # Concatenate information together concerning the error into a
    #   message string
    pymsg = tbinfo + "\n" + str(sys.exc_type)+ ": " + str(sys.exc_value)

    # Return python error messages for use with a script tool
    arcpy.AddError(pymsg)

    # Print Python error messages for use in Python/PythonWin
    print pymsg

del sCurI, sCurJ, sCurInt

The output are two text files with intersection matrix and intersection area matrix.

I'm not sure what exactly do you mean in problem [3]. The distance should be calculated for all species ranges or for species ranges which intersect or for intersection polygons?
0 Kudos