2

I have been using this tutorial to try to make a dot density map using python within QGIS, and my code shamelessly draws from the linked tutorial:

import random
src = "~/maps/SAMS_areas.shp"
tractLyr = QgsVectorLayer(src, "SAMS", "our")
popLyr =  QgsVectorLayer('Point?crs=epsg:3006', "counts" , "memory")
i = tractLyr.fieldNameIndex('counts')
features = tractLyr.getFeatures()
vpr = popLyr.dataProvider()
for feature in features:
  pop = feature.attributes()[i]
  density = pop
  found = 0
  dots = []
  g = feature.geometry()
  minx =  g.boundingBox().xMinimum()
  miny =  g.boundingBox().yMinimum()
  maxx =  g.boundingBox().xMaximum()
  maxy =  g.boundingBox().yMaximum()
  while found < density:
    x = random.uniform(minx,maxx)
    y = random.uniform(miny,maxy)
    pnt = QgsPoint(x,y)
    if g.contains(pnt):
      dots.append(pnt)
      found += 1
  geom = QgsGeometry.fromMultiPoint(dots)
  f = QgsFeature()
  f.setGeometry(geom)
  dotFeatures.append(f)
vpr.addFeatures(dotFeatures)
popLyr.updateExtents()
QgsMapLayerRegistry.instance().addMapLayers([popLyr,tractLyr])

I keep getting an error saying that none type object has no attribute bounding box, and I checked this other question where it is suggested that maybe the cause of such error is the format of the variables. I can confirm that my variables for counts are integers (I use a .csvt file and all). This error appears also if I try to use the dialogue box on the GUI. I wonder if this is because my shapefile has features that are represented by multiple polygons. I ended up with this setup because wanted to spread the dots only within the residential areas of each district/feature, what led to some districts being split in several polygons.

2

I modified your script to:

import random
src = "/home/zeito/pyqgis_data/polygon8.shp"
tractLyr = QgsVectorLayer(src, "SAMS", "ogr")
popLyr =  QgsVectorLayer('Point?crs=epsg:32612', "counts" , "memory")
i = tractLyr.fieldNameIndex('counts')
features = tractLyr.getFeatures()
vpr = popLyr.dataProvider()
dotFeatures = []
for feature in features:
  pop = feature.attributes()[i]
  density = pop
  found = 0
  dots = []
  g = feature.geometry()
  minx =  g.boundingBox().xMinimum()
  miny =  g.boundingBox().yMinimum()
  maxx =  g.boundingBox().xMaximum()
  maxy =  g.boundingBox().yMaximum()
  while found < density:
    x = random.uniform(minx,maxx)
    y = random.uniform(miny,maxy)
    pnt = QgsPoint(x,y)
    if g.contains(pnt):
      dots.append(pnt)
      found += 1
  geom = QgsGeometry.fromMultiPoint(dots)
  f = QgsFeature()
  f.setGeometry(geom)
  dotFeatures.append(f)
vpr.addFeatures(dotFeatures)
popLyr.updateExtents()
QgsMapLayerRegistry.instance().addMapLayers([popLyr,tractLyr])

for adapting to my test shapefile (polygon8.shp) and its projection (where it was also created the field 'counts'). Basically, your errors are in:

.
.
.
src = "/home/zeito/pyqgis_data/polygon8.shp" #it needs an absolute path
tractLyr = QgsVectorLayer(src, "SAMS", "ogr") #driver is 'ogr', not 'our'
.
.
.
dotFeatures = []  #not defined
.
.
.

After running the script at the Python Console of QGIS I got:

enter image description here

It works for generating the memory layer.

  • It did solve the script problem, and you may also add that I had forgotten to define the dotFeatures list as well. Now I get a script that runs, but I get the spinning ball of death, which is a different problem. – Kenji Mar 4 '16 at 10:08
  • Yes, it was also detected by me but I forgot to include it. Thanks for pointed out this omision. – xunilk Mar 4 '16 at 10:15

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.