2

The fields populated by running my script have a different length and precision in QGIS, than what appears in the output of the attribute table with a PDF. I should also mention that before the output is created the attribute table is joined with another attribute table, in case that makes a difference.

Creating and populating the new attributes.

primary = QgsField('Primary', QVariant.Double, "double",  2,  2)
huff_model.addAttribute(primary)
index_pri = huff_model.fieldNameIndex('Primary')

for feature in huff_model.getFeatures():
    probability = feature.attributes()
    ctuid = feature["CTUID"]
    if not probability[col_num]:
        print ("This mall does not exist")
    else:
        # Primary market values will go into this column
        if probability[col_num] >= .6:
            #print("Primary market area: {} ({})".format(ctuid, probability[col_num]))
            huff_model.changeAttributeValue(feature.id(), index_pri, probability[col_num])
        # Secondary market values will go into this column
        if .4 <= probability[col_num] < .6:
            #print("Secondary market area: {} ({})".format(ctuid, probability[col_num]))
            huff_model.changeAttributeValue(feature.id(), index_sec, probability[col_num])

# Delete all other features (rows) that do not have a probability in the primary and the secondary column
expr = QgsExpression("Primary is NULL and Secondary is NULL")
for f in huff_model.getFeatures(QgsFeatureRequest(expr)):
    huff_model.deleteFeature(f.id())

huff_model.updateExtents()
huff_model.commitChanges()
huff_model.updateFields()

Loading Print Composer and creating PDF

# Create the attribute using the map composer in QGIS and show the output in PDF format.
mapRenderer = iface.mapCanvas().mapRenderer()
c = QgsComposition(mapRenderer)
c.setPlotStyle(QgsComposition.Print)
x, y = 0, 0
w, h = c.paperWidth(), c.paperHeight()
composerMap = QgsComposerMap(c, x, y, w, h)

table = QgsComposerAttributeTable(c)
table.setComposerMap(composerMap)
table.setScale(1)
table.setVectorLayer(huff_model)
table.setMaximumNumberOfFeatures(huff_model.featureCount())
c.addItem(table)

# Checks for the existence of a file with the same name and removes it.
if os.path.isfile(PDF_file):
    os.remove(PDF_file)

# Set the properties of the PDF which will take and show the attribute table
printer = QPrinter()
printer.setOutputFormat(QPrinter.PdfFormat)
printer.setOutputFileName(PDF_file)
printer.setPaperSize(QSizeF(c.paperWidth(), c.paperHeight()), QPrinter.Millimeter)
printer.setFullPage(True)

pdfPainter = QPainter(printer)
paperRectMM = printer.pageRect(QPrinter.Millimeter)
paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
c.render(pdfPainter, paperRectPixel, paperRectMM)
pdfPainter.end()

In the image below you can see that the attribute corresponding to primary looks fine. There appears to be the correct precision and length.

Finished Script Attribute Table

enter image description here

However as seen below, in the PDF output of the attribute table, there are far more decimals than what's seen in the attribute table in QGIS.

Same Attribute Table in the PDF Output

enter image description here

There were no new calculations used to create the numbers in the "Primary" column. The original data had a length of 23 and precision of 15, and I want to reduce it to a length of 2 and a precision of 2. The second image with the PDF confirms this as there are exactly 15 decimals places. My guess is the output is still using the "old" format for some reason, I'm not sure why though. I want to make sure that any changes that I make to any field will be updated in the output, in this particular case, the changes to length and precision.

  • After you finish editing the fields, did you use huff_model.updateFields()? – Joseph Jan 17 '18 at 10:08
  • Do you mean after huff_model.commitChanges()? If so, yes, but it still comes up with the same result. – ShockDoctor Jan 17 '18 at 12:27
  • To clarify, the "Primary" field already exists (with length 23 and precision 15) and you want to change these to 2, 2? – Joseph Jan 17 '18 at 14:44
  • That's exactly it. – ShockDoctor Jan 17 '18 at 15:56
  • 1
    Could you please add the code showing how you are inserting the values to the new column and the code showing how you are loading the composer attribute table? I'm wondering if you should format the values before inserting them into your new column (e.g. new_value = float(round(old_value, 2))) – Joseph Jan 18 '18 at 10:05
1

Before inserting your values into your Primary column, you can format them to a certain float precision, i.e.

new_value = float(round(old_value, 2))

This will format values such as 0.742762386033321 to simply 0.74 which should be accepted by your new field.

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.