[Gfoss] Calcolare le dimensioni di stampa in scala a partire da una geometria con pyQgis

Luca Mandolesi mandoluca a gmail.com
Lun 25 Giu 2012 23:19:43 CEST


Allora, scusate il paciugo del work in progress.

Diciamo che nel mio mainapp faccio

from pyarchinit_print_utility import Print_utility

...
...

#collego la funzione al bottone
       def on_pushButton_pdf_exp_pressed(self):
		PU = Print_utility(self.iface, self.DATA_LIST)
		PU.first_batch_try()

Poi ho il file incriminato:

"""
/***************************************************************************
 testerDialog
								 A QGIS plugin
 test print
							 -------------------
		begin				 : 2012-06-20
		copyright			 : (C) 2012 by luca
		email				 : pyarchinit at gmail.com
 ***************************************************************************/

/***************************************************************************
 *																		   *
 *	 This program is free software; you can redistribute it and/or modify  *
 *	 it under the terms of the GNU General Public License as published by  *
 *	 the Free Software Foundation; either version 2 of the License, or	   *
 *	 (at your option) any later version.								   *
 *																		   *
 ***************************************************************************/
"""
import os

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import PyQt4.QtGui

from qgis.core import *
from qgis.gui import *

#from ui_tester import Ui_tester
# create the dialog for zoom to point
class Print_utility:
	if os.name == 'posix':
		HOME = os.environ['HOME']
	elif os.name == 'nt':
		HOME = os.environ['HOMEPATH']
	FILEPATH = os.path.dirname(__file__)
	LAYER_STYLE_PATH = ('%s%s%s%s') % (FILEPATH, os.sep, 'styles', os.sep)
	SRS = 3004
	
	layerUS = ""
	layerQuote = ""
	mapHeight = ""
	mapWidth = ""
	USLayerId = ""
	tav_num = ""
	us = ""
	uri = ""
	
	def __init__(self, iface, data):
		self.iface = iface
		self.data = data
		#self.area = area
		#self.us = us
		self.canvas = self.iface.mapCanvas()
		# set host name, port, database name, username and password

	"""
	def on_pushButton_runTest_pressed(self):
		self.first_batch_try()
    """
	def first_batch_try(self):
		#f = open("/test_print_2.txt", "w")
		#f.write(str(self.sito))
		#f.close()
		for i in range(len(self.data)):
			test = self.charge_layer_postgis(self.data[i].sito,
self.data[i].area, self.data[i].us)
			self.us = self.data[i].us
			if test != 0:
				self.test_bbox()
				tav_num= i+1
				self.print_map(tav_num)
			else:
				pass
			"""
			for i in self.data:
				self.charge_layer_postgis(i.sito,i.area,i.us)
				self.test_bbox()
				self.print_map(i)
			"""
	def converter_1_20(self, n):
		n *= 100
		res = n / 20
		return res

	def test_bbox(self):
		self.layerUS.select( [] ) # recuperi tutte le geometrie senza attributi
		featPoly = QgsFeature() # crei una feature vuota per il poligono

		dizionario_id_contains = {}
		lista_quote = []

		self.layerUS.nextFeature( featPoly ) # cicli sulle feature
recuperate, featPoly conterra la feature poligonale attuale
		bbox = featPoly.geometry().boundingBox() # recupera i punti nel bbox
del poligono

		self.height = self.converter_1_20(float(bbox.height())) * 0.5 #la
misura da cm e' portata in mm
		self.width = self.converter_1_20(float(bbox.width())) * 0.5 #la
misura da cm e' portata in mm
		
		#f = open("/test_paper_size_5.txt", "w")
		#f.write(str(self.width))
		#f.close()

	def getMapExtentFromMapCanvas(self,	 mapWidth, mapHeight, scale):
		#code from easyPrint plugin
		print "in methode: " + str(scale)

		xmin = self.canvas.extent().xMinimum()
		xmax = self.canvas.extent().xMaximum()
		ymin = self.canvas.extent().yMinimum()
		ymax = self.canvas.extent().yMaximum()
		xcenter = xmin + (xmax - xmin) / 2
		ycenter = ymin + (ymax - ymin) / 2

		mapWidth = mapWidth * scale / 1000 #misura in punti
		mapHeight = mapHeight * scale / 1000 #misura in punti
		
		f = open("/test_paper_size_3.txt", "w")
		f.write(str(mapWidth))
		f.close()

		minx = xcenter - mapWidth / 2
		miny = ycenter - mapHeight / 2
		maxx = xcenter + mapWidth / 2
		maxy = ycenter + mapHeight / 2

		return QgsRectangle(minx,  miny,  maxx,	 maxy)

	def print_map(self, tav_num):
		self.tav_num = tav_num

		mapRenderer = self.iface.mapCanvas().mapRenderer()
		
		c = QgsComposition(mapRenderer)
		c.setPlotStyle(QgsComposition.Print)

		#map - this item tells the libraries where to put the map itself.
Here we create a map and stretch it over the whole paper size:
		x, y = 0, 0 #angolo 0, o in alto a sx
		width, height = self.width*5, self.height*5 #da un valore alla
larghezza e altezza del foglio aumentato di 5 per dare un margine
		dpi = 100 #viene settata la risoluzione di stampa
		
		c.setPaperSize(width, height) #setta le dimensioni della pagina
		
		f = open("/test_paper_size_1.txt", "w")
		f.write(str(width))
		f.close()
		
		composerMap = QgsComposerMap(c, x, y, width, height) #crea un
mapComposer passandogli la classere Composition che a sua volta ha
incapsulato con la classe mapRenderer il canvas corrente
		
		rect = self.getMapExtentFromMapCanvas(c.paperWidth(),
c.paperHeight(),	 20.0) #ricava la mappa in scala da inserire nel
compositore passando le dimensioni di pagina in mm e ricavandoli in
punti
		
		f = open("/test_paper_size_2.txt", "w")
		f.write(str(c.paperWidth()))
		f.close()
		
		composerMap.setNewExtent(rect) #setta l'estensione della mappa

		c.addItem(composerMap) #aggiunge la mappa alla composizione c

		#aggiunge la scale bar
		item = QgsComposerScaleBar(c)
		item.setStyle('Numeric') # optionally modify the style
		item.setComposerMap(composerMap)
		item.applyDefaultSize()
		c.addItem(item)

		#width = 1189
		#height = 841


		#c.setPaperSize(width, height)
		c.setPrintResolution(dpi) #setta la risoluzione di stampa

		#Output to a raster image
		#The following code fragment shows how to render a composition to a
raster image:
		
		f = open("/test_paper_size_4.txt", "w")
		f.write(str(dpi))
		f.close()
		
		dpmm = dpi / 25.4 #ricava il valore dei punti per mm
		width_point = float(dpmm * c.paperWidth())
		height_point = float(dpmm * c.paperHeight())

		# create output image and initialize it
		image = QImage(QSize(width_point, height_point), QImage.Format_ARGB32)
		image.setDotsPerMeterX(dpmm * 1000)
		image.setDotsPerMeterY(dpmm * 1000)
		image.fill(0)

		# render the composition
		imagePainter = QPainter(image)
		sourceArea = QRectF(0, 0, c.paperWidth(), c.paperHeight()) #viene
settata l'area sorgente con le misure in mm della carta
		targetArea = QRectF(0, 0, width_point, height_point) #viene settata
l'area in cui inserire la mappa con le misure in punti per mm
		c.render(imagePainter, targetArea, sourceArea)
		imagePainter.end()
		tav_name = ("/pyarchinit_print_tester_folder/Tavola_%d_us_%d.png") %
(self.tav_num+1, self.us)
		image.save(str(tav_name), "png")
			
		
		#QgsMapLayerRegistry.instance().removeMapLayer(layer_id)

		#Output to PDF
		#The following code fragment renders a composition to a PDF file:
		"""
		printer = QPrinter()
		printer.setOutputFormat(QPrinter.PdfFormat)
		printer.setOutputFileName("/out.pdf")
		printer.setPaperSize(QSizeF(self.mapWidth, self.mapHeight),
QPrinter.Millimeter)
		printer.setFullPage(True)
		printer.setColorMode(QPrinter.Color)
		printer.setResolution(c.printResolution())

		pdfPainter = QPainter(printer)
		paperRectMM = printer.pageRect(QPrinter.Millimeter)
		paperRectPixel = printer.pageRect(QPrinter.DevicePixel)
		c.render(pdfPainter, paperRectPixel, paperRectMM)
		pdfPainter.end()
		"""
		QgsMapLayerRegistry.instance().removeMapLayer(self.USLayerId)

	def open_connection(self):
		self.uri = QgsDataSourceURI()
		self.uri.setConnection('127.0.0.1','5432', 'mioDB', 'postgres', 'miapass')	


	def charge_layer_postgis(self, sito, area, us):
		self.open_connection()
		
		srs = QgsCoordinateReferenceSystem(3004,
QgsCoordinateReferenceSystem.PostgisCrsId)

		gidstr = ("scavo_s = '%s' and area_s = '%s' and us_s = '%d'") %
(sito, area, us)
		
		#f = open("/test_print.txt", "w")
		#f.write(str(gidstr))
		#f.close()
		
		self.uri.setDataSource("public", "pyarchinit_us_view", "the_geom", gidstr)
		
		self.layerUS = QgsVectorLayer(self.uri.uri(), "US", "postgres")

		if	self.layerUS.isValid() == True:
			self.layerUS.setCrs(srs)
			self.USLayerId = self.layerUS.getLayerID()
			#self.mapLayerRegistry.append(USLayerId)
			style_path = ('%s%s') % (self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
			self.layerUS.loadNamedStyle(style_path)
			self.iface.mapCanvas().setExtent(self.layerUS.extent())
			QgsMapLayerRegistry.instance().addMapLayer( self.layerUS, True)
		else:
			return 0
			#QMessageBox.warning(self, "Messaggio", "Geometria inesistente",
QMessageBox.Ok)

		"""
		gidstr = "sito = 'test'"
		uri.setDataSource("public", "pyarchinit_punti_rif", "the_geom", gidstr)
		self.layerGriglia = QgsVectorLayer(uri.uri(), "Griglia a 50 cm", "postgres")

		if	self.layerGriglia.isValid() == True:
			self.layerGriglia.setCrs(srs)
			layerGrigliaId =  self.layerGriglia.getLayerID()
			#self.mapLayerRegistry.append(USLayerId)
			#style_path = ('%s%s') % (self.LAYER_STYLE_PATH, 'stile_griglia.qml')
			#self.layerGriglia.loadNamedStyle(style_path)
			#self.iface.mapCanvas().setExtent(self.layerUS.extent())
			QgsMapLayerRegistry.instance().addMapLayer( self.layerGriglia, True)
		else:
			print "layerGriglia US is not valid!!!"



		
		uri.setDataSource("public", "pyarchinit_uscaratterizzazioni_view",
"the_geom", gidstr)
		layerCar = QgsVectorLayer(uri.uri(), "Unita' Stratigrafiche", "postgres")

		if	layerCar.isValid() == True:
			layerCar.setCrs(srs)
			CARLayerId = layerCar.getLayerID()
			self.mapLayerRegistry.append(CARLayerId)
			#style_path = ('%s%s') % (self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
			# self.layerUS.loadNamedStyle(style_path)
			QgsMapLayerRegistry.instance().addMapLayer(layerCar, True)
		else:
			print "Layer Caratterizzazioni is not valid!!!"

		
		gidstr = "gid = 2257  or gid = 2849 or gid = 2443  or gid = 2370 or
gid = 2297	 or gid = 2852	or gid = 2299  or gid = 2225 or gid =
2226	or gid = 2448 or gid = 2862 or gid = 2863 or gid = 2717 or gid =
2718  or gid = 2427  or gid = 2429	 or gid = 2245	or gid = 2652  or
gid = 2285 or gid = 2287 or gid = 2288 or gid = 2289 or gid = 2844  or
gid = 2290 or gid = 2475 or gid = 2845 or gid = 2328"

		uri.setDataSource("public", "pyarchinit_quote", "the_geom", gidstr)
		self.layerQuote = QgsVectorLayer(uri.uri(), "Quote", "postgres")

		if	self.layerQuote.isValid() == True:
			self.layerQuote.setCrs(srs)
			QuoteLayerId = self.layerQuote.getLayerID()
			#self.mapLayerRegistry.append(QuoteLayerId)
			#style_path = ('%s%s') % (self.LAYER_STYLE_PATH, 'us_caratterizzazioni.qml')
			# self.layerUS.loadNamedStyle(style_path)
			QgsMapLayerRegistry.instance().addMapLayer(self.layerQuote, True)
		else:
			print "Layer Quote is not valid!!!"

		#Print section

		# create image
		"""


Maggiori informazioni sulla lista Gfoss