5

I want to calculate the frequency of observation of an animal in a forest habitat within the different zones of my study area. To do this I will use the simple equation (number of individuals)/(survey effort). I want to do this within a grid of 150mx150m, where a greyscale gradient will indicate the varying population densities.

So far, I have a polygon grid (fishnet) clipped to an area of study of 150mx150m. The survey effort per grid has been calculated using the 'sum line' function. (vector->analysis tools->sum line length)

enter image description here

Picture: a visual representation of the field site (green polygon), with survey trails (pink lines) and observation locations (dark red points).

Next, I want to calculate the number of individuals observed per grid square. The point shapefile representing the observation locations contains a feature in the attributes table called 'cluster size' which is the number of animals that were observed for any observation point. I want to have the total addition of 'cluster size' for all points within each grid cell. Preferably as a feature (column) in the 'sum line' shapefile so that I can then make a simple calculation using the equation (number of individuals)/(survey effort) for population density within each cell of the grid.

I have tried using the point count function found in vector->analysis but this provides only the number of points per grid cell, while I would want the sum of cluster sizes per grid cell. Can anyone suggest how to do this?

I am using QGIS 2.18.7

  • Your last part is unclear: what do you mean with Preferably as a feature in the 'line sum' feature shapefile? How do you think to connect the sum value stored in the point to a line, which may cross many different points at the same time? Moreover, what do you mean with 'line sum' function? – mgri Jul 7 '17 at 9:06
  • sorry some mistypes in there: i) I want the sum of the cluster sizes within each grid as an extra column (feature) for the line sum shapefile ii) I was hoping that since each cell has been given an ID value in the line sum shapefile that I could link them using that iii) Line sum function = Vector -> analysis tools -> sum line length – Nebulloyd Jul 7 '17 at 9:10
  • Thanks, but you didn't answer the questions: what does it is the 'line sum' function? Where did you find it and how did you use it? Then, a line may cross different grid cells and, since each one of them stores a different sum for the cluster sizes, which is the final value to assign to it? I hope it is clearer by now. – mgri Jul 7 '17 at 9:19
  • sorry the line sum gives the sum length and line count of line features where they occur within the polygons of a shapefile. In this case the lines are the survey trails and the polygons are the cells in the grid. So I already have a column in the attributes table that tells me how much survey effort was designated to each cell in the grid as an accumulative length of the sections of the survey trails that occurred in each grid cell it can be found in QGIS 2.18.7 via the Vector down menu. I used it as explained above. – Nebulloyd Jul 7 '17 at 10:03
  • 1
    For the "observations per sampling grid" did you try the built-in QGIS tool Count points in polygons? It's under the Vector=>Analysis menu. – Micha Jul 7 '17 at 10:10
3

Firstly, you may run a simple code from the Python Console. You only need to preliminarily load the point layer and the polygon layer in the Layers Panel and then typing their name and the field name where the cluster size value is stored:

from PyQt4.QtCore import QVariant

point_layer_name = 'points' # name of the point layer
grid_layer_name = 'grid' # name of the polygon layer
cluster_size_field = 'observations' # field name where the observations are stored

point_layer = QgsMapLayerRegistry.instance().mapLayersByName(point_layer_name)[0]
grid_layer = QgsMapLayerRegistry.instance().mapLayersByName(grid_layer_name)[0]

# Create the output layer
crs = grid_layer.crs().toWkt()
outLayer = QgsVectorLayer('Polygon?crs='+ crs, 'outLayer' , 'memory')
prov = outLayer.dataProvider()
fields = grid_layer.pendingFields() # Fields from the input layer
fields.append(QgsField('OBS_SUM', QVariant.Int, '', 10, 0))
prov.addAttributes(fields) # Add input layer fields to the outLayer
outLayer.updateFields()

points = [feat for feat in point_layer.getFeatures()]
cells = [ft for ft in grid_layer.getFeatures()]

all_points = {}
index = QgsSpatialIndex() # this spatial index contains all the features of the point layer
for point in points:
    index.insertFeature(point)
    all_points[point.id()] = point

for cell in cells:
    obs_sum = 0
    inAttr = cell.attributes() # Input attributes
    tmp_geom = cell.geometry() #Input geometry
    idsList = index.intersects(tmp_geom.boundingBox())
    for idf in idsList:
        tmp_pt_geom = all_points[idf].geometry()
        if tmp_pt_geom.intersects(tmp_geom):
            obs_sum += all_points[idf][cluster_size_field]

    inAttr.append(obs_sum)
    outGeom = QgsFeature()
    outGeom.setAttributes(inAttr) # Output attributes
    outGeom.setGeometry(tmp_geom) # Output geometry
    prov.addFeatures([outGeom]) # Output feature
# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

You will obtain a new polygon memory layer that stores the sum of the observations within each cell (the values will be stored in the "OBS_SUM" field).

Once you have done this, you can execute a join with the original point layer. For doing this, you may run the Join attributes by location algorithm from the Processing Toolbox using this configuration:

enter image description here

It will return a new point layer that stores the joined attributes from both the grid layer and the layer returned by the previous code.

By now, you should have all the elements for joining again your points to the line shapefile (since it is still unclear how you want to do that, I can only suggest using again the Join attributes by location algorithm and setting a value greater than 0 for the Precision parameter).

  • 1
    As I already had the layers loaded I simply followed the tutorial in the link from the above answer, however I believe this to be a valid answer as well. – Nebulloyd Jul 7 '17 at 12:01
  • @Nebulloyd I'm glad you found a solution. The code snippet does almost the same job of the Join attributes by location algorithm. – mgri Jul 7 '17 at 12:09
2

You need to perform a 'spatial join' to transfer the attributes of the points to each grid cell and sum the counts together. Here is a link to a tutorial on doing just that

  • Following this tutorial was an excellent and efficient means to getting the result I was after – Nebulloyd Jul 7 '17 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.