3

I am currently digitizing an old archaeological excavation. I have created the 2m grid where finds were excavated, and have created centroids within each grid. All the corresponding finds has then been joined to the centroids and saved as a new point layer:

enter image description here

The point layer contains multiple points stacked upon each other, because they share the same "local coordinates" ie. 450/560.

What I want to do, is to sum the amount of "something" within between different columns. 2] Yellow marks "Amount" and where two points share the same coordinates

So I should like to merge all rows with the same X and Y values and have their amount summed.

I should in the end, like to end up with a new polygon layer, where each m2 contains the SUM of all the finds from that specific m2, based on different query's. So it will be possible to graduate colors based on finds intensity

4
  • Since I don't know how to directly do it with QGIS, would you accept PyQGIS solutions?
    – mgri
    Feb 16, 2017 at 15:56
  • 1
    @mgri I accept everything, as long as I can replicate it. I haven't done any python scripting in QGIS so far. But I guess I can manage to copy paste someones script
    – eyesore
    Feb 16, 2017 at 15:58
  • Are you only interested on the "Amount" field?
    – mgri
    Feb 16, 2017 at 16:08
  • Yes, at the moment I am just interested in getting the amount summed for each corresponding m2
    – eyesore
    Feb 16, 2017 at 16:12

3 Answers 3

2

You may use this code as a new script from Processing Toolbox (from the main QGIS Window, go to Processing and then click on Toolbox. From the Processing toolbox (just activated on the right side of the main QGIS window), go to Create new script menu under the Tools group in the Scripts algorithms block of the toolbox. Then, copy & paste my code):

##Centroids=vector point
##Polygon=vector polygon

from qgis.core import *
from qgis.PyQt.QtCore import QVariant

p_layer = processing.getObject(Centroids)
crs = p_layer.crs().toWkt()

poly_layer = processing.getObject(Polygon)

# Create the output layer
outLayer = QgsVectorLayer('Polygon?crs='+ crs, 'Amounts' , 'memory')
prov = outLayer.dataProvider()
fields = poly_layer.pendingFields()
fields.append(QgsField('Amounts', QVariant.Int, '', 10, 0)) # Name for the new field in the output layer
prov.addAttributes(fields)
outLayer.updateFields()

all_points = {}
index = QgsSpatialIndex()
for ft in p_layer.getFeatures():
    if ft["Amount"]:
        index.insertFeature(ft)
        all_points[ft.id()] = ft["Amount"]

for feat in poly_layer.getFeatures():
    geom = feat.geometry()
    attrs = feat.attributes()
    idsList = index.intersects(geom.boundingBox())
    attrs.append(sum(all_points[x] for x in idsList))
    outFeat = QgsFeature()
    outFeat.setAttributes(attrs)
    outFeat.setGeometry(geom)
    prov.addFeatures([outFeat])

# Add the layer to the Layers panel
QgsMapLayerRegistry.instance().addMapLayer(outLayer)

The result will be a new polygon memory layer which stores the same original attributes, plus one additional field containing the required sum.

If you want to change the field for the sum, slightly edit the code where it's specified (i.e. the ft["Amount"] line).

7
  • You sir are a genius! It worked. Many, many thanks. I was a bit confused to begin with because of a whole lot of "0" values in the Amounts column, but it looks like it also retains all the m2 cells with no information. Let me just test it for some different data sets, and then I shall report back.
    – eyesore
    Feb 16, 2017 at 16:57
  • I'm glad it worked! The code makes a copy of the fields from the input layer and adds the field called "Amounts" (the calculations are only made for the specified field!)
    – mgri
    Feb 16, 2017 at 17:00
  • Do you have any idea what causes this error: unsupported operand type(s) for +: 'long' and 'QPyNullVariant' See log for more details
    – eyesore
    Feb 16, 2017 at 17:10
  • 1
    It was actually Null values. I just replaced them all with 0's and it works a dream. Thanks a lot!
    – eyesore
    Feb 16, 2017 at 17:36
  • 1
    Absolutely! Thanks again! This really saved my life. Good day to you Sir!
    – eyesore
    Feb 16, 2017 at 17:41
2

This can be done with Data Management Tools> Join Attributes by Location:

enter image description here

It will give you a number of stats for the values. If there are more than one point you must "Take summary of intersecting features".

1

You can easily calculate the amount of points within a polygon (Vector-->Analysis Tools--> Points within Polygon). You now have new shapefile with a sum of the amount of finds within a polygon. Not long ago I had to do the exact same thing:

enter image description here In the column PNTCNT(pointcount) it shows the sum of finds within a polygon.

enter image description here Than simply graduate the colors based upon this column.

P.S. I am a archaeologist myself and love to see the use of QGIS instead of MapInfo

3
  • Does this method find the number of points or the sum of the attributes in the "Amount" field?
    – mgri
    Feb 16, 2017 at 16:04
  • Thanks a lot! I did actually try this out, but it just sums the amount of points, and not the actual amount of finds.
    – eyesore
    Feb 16, 2017 at 16:07
  • You are right I did not understand the question completely than. Feb 16, 2017 at 19:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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