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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

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

mando
Salve a tutti,
vorrei poter realizzare tramite pyQgis un sistema di stampa delle mie
geometrie che mi esportino le piante in una scala prescelta
(possibilmente 1:20).

Per esempio:

se ho una geometria che è racchiusa in un box che misura 1 x 1 metri,
per stamparla in scala 1:20, dovrei caricare un foglio di 5 x 5 cm e
inserirci la geometria.


Come posso realizzare un box intorno ad una geometria, ricavarne
altezza e larghezza, ricavare i valori del del foglio in 1:20 e
inserirci il mio poligono?

Guardando sul cook book di pyQgis ci sono vari metodi, che però
prevedono di adattare la geometria alla dimensione del foglio e non
viceversa.

Grazie a tutti per qualsiasi suggerimento.

Ciao

Luca
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012
Reply | Threaded
Open this post in threaded view
|

Re: Calcolare le dimensioni di stampa in scala a partire da una geometria con pyQgis

Marco Curreli
On 15:36 Wed 20 Jun     , Luca Mandolesi wrote:

> Per esempio:
>
> se ho una geometria che è racchiusa in un box che misura 1 x 1 metri,
> per stamparla in scala 1:20, dovrei caricare un foglio di 5 x 5 cm e
> inserirci la geometria.
>
>
> Come posso realizzare un box intorno ad una geometria, ricavarne
> altezza e larghezza, ricavare i valori del del foglio in 1:20 e
> inserirci il mio poligono?
>

Un po' di tempo fa avevo inserito nel wiki uno script di shell che
calcola le dimensioni di una mappa in metri e in pixel, note le coordinate
dei vertici e la risoluzione di un raster (la dimensione del lato di un
pixel quadrato). Non so se può essere utile.
http://wiki.gfoss.it/index.php/Dimensione_di_una_mappa_dalle_coordinate

Ciao,
  Marco

_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012
Reply | Threaded
Open this post in threaded view
|

Re: Calcolare le dimensioni di stampa in scala a partire da una geometria con pyQgis

mando
Ciao Marco,
grazie per la dritta. Studianto un po' il plugin easyPrint sono
riuscito a stampare qualcosa in 1:20...

Ora però non capisco perchè, quando vado a caricare la singola
geometria tramite pyQgis e ho già caricato un layer di base tramite il
carica layer nativo di QGis connesso al medesimo DB, ottengo un too
many clients connection...nonostante il mio db abbia come opzione -1
nei limiti di connessione...

La funzione per aprire la connessione sta dentro ad una mia classe che
viene chiamata a sua volta da una interfaccia tramite un import...è
come se facendo l'import, la funzione faccia la connessione anche se
non chiamata, e non solamente nel momento in cui voglio caricare il
layer.

Se invece non ho alcun layer caricato da postgis dentro Qgis, posso
fare un ciclo for e caricare tutte le geometrie che voglio. Peccato
però che alla fine del processo, se provo a caricare un altro layer
ottengo lo stesso problema.

Non capisco lo sbaglio e come scrivere correttamente una funzione di
connessione via pyQgis, senza interferire con il carica layer nativo
di Qgis.

Ciao

Luca





2012/6/25 Marco Curreli <[hidden email]>:

> On 15:36 Wed 20 Jun     , Luca Mandolesi wrote:
>> Per esempio:
>>
>> se ho una geometria che è racchiusa in un box che misura 1 x 1 metri,
>> per stamparla in scala 1:20, dovrei caricare un foglio di 5 x 5 cm e
>> inserirci la geometria.
>>
>>
>> Come posso realizzare un box intorno ad una geometria, ricavarne
>> altezza e larghezza, ricavare i valori del del foglio in 1:20 e
>> inserirci il mio poligono?
>>
>
> Un po' di tempo fa avevo inserito nel wiki uno script di shell che
> calcola le dimensioni di una mappa in metri e in pixel, note le coordinate
> dei vertici e la risoluzione di un raster (la dimensione del lato di un
> pixel quadrato). Non so se può essere utile.
> http://wiki.gfoss.it/index.php/Dimensione_di_una_mappa_dalle_coordinate
>
> Ciao,
>  Marco
>
> _______________________________________________
> [hidden email]
> http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
> Questa e' una lista di discussione pubblica aperta a tutti.
> Non inviate messaggi commerciali.
> I messaggi di questa lista non rispecchiano necessariamente
> le posizioni dell'Associazione GFOSS.it.
> 594 iscritti all'11.6.2012
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012
Reply | Threaded
Open this post in threaded view
|

Re: Calcolare le dimensioni di stampa in scala a partire da una geometria con pyQgis

giohappy

Puoi condividere la parte di codice con cui fai la connessione?

giovanni

Inviato da dispositivo mobile

Il giorno 25/giu/2012 22.31, "Luca Mandolesi" <[hidden email]> ha scritto:
Ciao Marco,
grazie per la dritta. Studianto un po' il plugin easyPrint sono
riuscito a stampare qualcosa in 1:20...

Ora però non capisco perchè, quando vado a caricare la singola
geometria tramite pyQgis e ho già caricato un layer di base tramite il
carica layer nativo di QGis connesso al medesimo DB, ottengo un too
many clients connection...nonostante il mio db abbia come opzione -1
nei limiti di connessione...

La funzione per aprire la connessione sta dentro ad una mia classe che
viene chiamata a sua volta da una interfaccia tramite un import...è
come se facendo l'import, la funzione faccia la connessione anche se
non chiamata, e non solamente nel momento in cui voglio caricare il
layer.

Se invece non ho alcun layer caricato da postgis dentro Qgis, posso
fare un ciclo for e caricare tutte le geometrie che voglio. Peccato
però che alla fine del processo, se provo a caricare un altro layer
ottengo lo stesso problema.

Non capisco lo sbaglio e come scrivere correttamente una funzione di
connessione via pyQgis, senza interferire con il carica layer nativo
di Qgis.

Ciao

Luca





2012/6/25 Marco Curreli <[hidden email]>:
> On 15:36 Wed 20 Jun     , Luca Mandolesi wrote:
>> Per esempio:
>>
>> se ho una geometria che è racchiusa in un box che misura 1 x 1 metri,
>> per stamparla in scala 1:20, dovrei caricare un foglio di 5 x 5 cm e
>> inserirci la geometria.
>>
>>
>> Come posso realizzare un box intorno ad una geometria, ricavarne
>> altezza e larghezza, ricavare i valori del del foglio in 1:20 e
>> inserirci il mio poligono?
>>
>
> Un po' di tempo fa avevo inserito nel wiki uno script di shell che
> calcola le dimensioni di una mappa in metri e in pixel, note le coordinate
> dei vertici e la risoluzione di un raster (la dimensione del lato di un
> pixel quadrato). Non so se può essere utile.
> http://wiki.gfoss.it/index.php/Dimensione_di_una_mappa_dalle_coordinate
>
> Ciao,
>  Marco
>
> _______________________________________________
> [hidden email]
> http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
> Questa e' una lista di discussione pubblica aperta a tutti.
> Non inviate messaggi commerciali.
> I messaggi di questa lista non rispecchiano necessariamente
> le posizioni dell'Associazione GFOSS.it.
> 594 iscritti all'11.6.2012
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012

_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012
Reply | Threaded
Open this post in threaded view
|

Re: Calcolare le dimensioni di stampa in scala a partire da una geometria con pyQgis

mando
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 : [hidden email]
 ***************************************************************************/

/***************************************************************************
 *   *
 * 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
                """
_______________________________________________
[hidden email]
http://lists.gfoss.it/cgi-bin/mailman/listinfo/gfoss
Questa e' una lista di discussione pubblica aperta a tutti.
Non inviate messaggi commerciali.
I messaggi di questa lista non rispecchiano necessariamente
le posizioni dell'Associazione GFOSS.it.
594 iscritti all'11.6.2012