Example #1
0
    def render(self):
        """Render the map composition to an image and save that to disk.

        :returns: A three-tuple of:
            * str: image_path - absolute path to png of rendered map
            * QImage: image - in memory copy of rendered map
            * QRectF: target_area - dimensions of rendered map
        :rtype: tuple
        """
        LOGGER.debug('InaSAFE Map renderComposition called')
        # NOTE: we ignore self.composition.printAsRaster() and always rasterise
        width = int(self.page_dpi * self.page_width / 25.4)
        height = int(self.page_dpi * self.page_height / 25.4)
        image = QtGui.QImage(QtCore.QSize(width, height),
                             QtGui.QImage.Format_ARGB32)
        image.setDotsPerMeterX(dpi_to_meters(self.page_dpi))
        image.setDotsPerMeterY(dpi_to_meters(self.page_dpi))

        # Only works in Qt4.8
        #image.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        image.fill(55 + 255 * 256 + 255 * 256 * 256)
        image_painter = QtGui.QPainter(image)
        source_area = QtCore.QRectF(0, 0, self.page_width, self.page_height)
        target_area = QtCore.QRectF(0, 0, width, height)
        self.composition.render(image_painter, target_area, source_area)
        image_painter.end()
        image_path = unique_filename(prefix='mapRender_',
                                     suffix='.png',
                                     dir=temp_dir())
        image.save(image_path)
        return image_path, image, target_area
Example #2
0
    def render(self):
        """Render the map composition to an image and save that to disk.

        :returns: A three-tuple of:
            * str: myImagePath - absolute path to png of rendered map
            * QImage: myImage - in memory copy of rendered map
            * QRectF: myTargetArea - dimensions of rendered map
        :rtype: tuple
        """
        LOGGER.debug('InaSAFE Map renderComposition called')
        # NOTE: we ignore self.composition.printAsRaster() and always rasterise
        myWidth = int(self.pageDpi * self.pageWidth / 25.4)
        myHeight = int(self.pageDpi * self.pageHeight / 25.4)
        myImage = QtGui.QImage(QtCore.QSize(myWidth, myHeight),
                               QtGui.QImage.Format_ARGB32)
        myImage.setDotsPerMeterX(dpi_to_meters(self.pageDpi))
        myImage.setDotsPerMeterY(dpi_to_meters(self.pageDpi))

        # Only works in Qt4.8
        #myImage.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        myImage.fill(55 + 255 * 256 + 255 * 256 * 256)
        myImagePainter = QtGui.QPainter(myImage)
        mySourceArea = QtCore.QRectF(0, 0, self.pageWidth,
                                     self.pageHeight)
        myTargetArea = QtCore.QRectF(0, 0, myWidth, myHeight)
        self.composition.render(myImagePainter, myTargetArea, mySourceArea)
        myImagePainter.end()
        myImagePath = unique_filename(prefix='mapRender_',
                                      suffix='.png',
                                      dir=temp_dir())
        myImage.save(myImagePath)
        return myImagePath, myImage, myTargetArea
Example #3
0
    def render(self):
        """Render the map composition to an image and save that to disk.

        :returns: A three-tuple of:
            * str: myImagePath - absolute path to png of rendered map
            * QImage: myImage - in memory copy of rendered map
            * QRectF: myTargetArea - dimensions of rendered map
        :rtype: tuple
        """
        LOGGER.debug('InaSAFE Map renderComposition called')
        # NOTE: we ignore self.composition.printAsRaster() and always rasterise
        myWidth = (int)(self.pageDpi * self.pageWidth / 25.4)
        myHeight = (int)(self.pageDpi * self.pageHeight / 25.4)
        myImage = QtGui.QImage(QtCore.QSize(myWidth, myHeight),
                               QtGui.QImage.Format_ARGB32)
        myImage.setDotsPerMeterX(dpi_to_meters(self.pageDpi))
        myImage.setDotsPerMeterY(dpi_to_meters(self.pageDpi))

        # Only works in Qt4.8
        #myImage.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        myImage.fill(55 + 255 * 256 + 255 * 256 * 256)
        myImagePainter = QtGui.QPainter(myImage)
        mySourceArea = QtCore.QRectF(0, 0, self.pageWidth, self.pageHeight)
        myTargetArea = QtCore.QRectF(0, 0, myWidth, myHeight)
        self.composition.render(myImagePainter, myTargetArea, mySourceArea)
        myImagePainter.end()
        myImagePath = unique_filename(prefix='mapRender_',
                                      suffix='.png',
                                      dir=temp_dir())
        myImage.save(myImagePath)
        return myImagePath, myImage, myTargetArea
Example #4
0
    def grow_legend(self):
        """Grow the legend pixmap enough to accommodate one more legend entry.
        """
        LOGGER.debug('InaSAFE Map Legend extendLegend called')
        if self.legendImage is None:

            self.legendImage = QtGui.QImage(self.legendWidth, 95,
                                            QtGui.QImage.Format_RGB32)
            self.legendImage.setDotsPerMeterX(dpi_to_meters(self.dpi))
            self.legendImage.setDotsPerMeterY(dpi_to_meters(self.dpi))

            # Only works in Qt4.8
            #self.legendImage.fill(QtGui.QColor(255, 255, 255))
            # Works in older Qt4 versions
            self.legendImage.fill(255 + 255 * 256 + 255 * 256 * 256)
            myPainter = QtGui.QPainter(self.legendImage)
            myFontWeight = QtGui.QFont.Bold
            myItalicsFlag = False
            myFont = QtGui.QFont('verdana',
                                 self.legendFontSize,
                                 myFontWeight,
                                 myItalicsFlag)
            myPainter.setFont(myFont)
            myPainter.drawText(10, 25, self.legendTitle)

            if self.legendUnits is not None:
                myFontWeight = QtGui.QFont.StyleNormal
                myItalicsFlag = True
                legendUnitsFontSize = self.legendFontSize / 2
                myFont = QtGui.QFont(
                    'verdana',
                    legendUnitsFontSize,
                    myFontWeight,
                    myItalicsFlag)
                myPainter.setFont(myFont)
                myPainter.drawText(10, 45, self.legendUnits)

        else:
            # extend the existing legend down for the next class
            myImage = QtGui.QImage(
                self.legendWidth,
                self.legendImage.height() + self.legendIncrement,
                QtGui.QImage.Format_RGB32)
            myImage.setDotsPerMeterX(dpi_to_meters(self.dpi))
            myImage.setDotsPerMeterY(dpi_to_meters(self.dpi))
            # Only works in Qt4.8
            #myImage.fill(QtGui.qRgb(255, 255, 255))
            # Works in older Qt4 versions
            myImage.fill(255 + 255 * 256 + 255 * 256 * 256)
            myPainter = QtGui.QPainter(myImage)

            myRect = QtCore.QRectF(0, 0,
                                   self.legendImage.width(),
                                   self.legendImage.height())
            myPainter.drawImage(myRect, self.legendImage, myRect)
            self.legendImage = myImage
Example #5
0
    def test_windowsDrawingArtifacts(self):
        """Test that windows rendering does not make artifacts"""
        # sometimes spurious lines are drawn on the layout
        LOGGER.info('Testing windowsDrawingArtifacts')
        myPath = unique_filename(
            prefix='artifacts',
            suffix='.pdf',
            dir=temp_dir('test'))
        myMap = Map(IFACE)
        setup_printer(myPath)
        myMap.setup_composition()

        myImage = QtGui.QImage(10, 10, QtGui.QImage.Format_RGB32)
        myImage.setDotsPerMeterX(dpi_to_meters(300))
        myImage.setDotsPerMeterY(dpi_to_meters(300))
        #myImage.fill(QtGui.QColor(250, 250, 250))
        # Look at the output, you will see antialiasing issues around some
        # of the boxes drawn...
        # myImage.fill(QtGui.QColor(200, 200, 200))
        myImage.fill(200 + 200 * 256 + 200 * 256 * 256)
        myFilename = os.path.join(temp_dir(), 'greyBox')
        myImage.save(myFilename, 'PNG')
        for i in range(10, 190, 10):
            myPicture = QgsComposerPicture(myMap.composition)
            myPicture.setPictureFile(myFilename)
            if qgis_version() >= 10800:  # 1.8 or newer
                myPicture.setFrameEnabled(False)
            else:
                myPicture.setFrame(False)
            myPicture.setItemPosition(i,  # x
                                      i,  # y
                                      10,  # width
                                      10)  # height
            myMap.composition.addItem(myPicture)
            # Same drawing drawn directly as a pixmap
            # noinspection PyCallByClass,PyTypeChecker,PyArgumentList
            myPixmapItem = myMap.composition.addPixmap(
                QtGui.QPixmap.fromImage(myImage))
            myPixmapItem.setOffset(i, i + 20)
            # Same drawing using our drawImage Helper
            myWidthMM = 1
            myMap.draw_image(myImage, myWidthMM, i, i + 40)

        myImagePath, _, _ = myMap.render()
        # when this test no longer matches our broken render hash
        # we know the issue is fixed

        myTolerance = 0
        myFlag, myMessage = check_images(
            'windowsArtifacts',
            myImagePath,
            myTolerance)
        myMessage += ('\nWe want these images to match, if they do not '
                      'there may be rendering artifacts in windows.\n')
        assert myFlag, myMessage
Example #6
0
    def grow_legend(self):
        """Grow the legend pixmap enough to accommodate one more legend entry.
        """
        LOGGER.debug('InaSAFE Map Legend extendLegend called')
        if self.legend_image is None:

            self.legend_image = QtGui.QImage(
                self.legend_width, 95, QtGui.QImage.Format_RGB32)
            self.legend_image.setDotsPerMeterX(dpi_to_meters(self.dpi))
            self.legend_image.setDotsPerMeterY(dpi_to_meters(self.dpi))

            # Only works in Qt4.8
            #self.legendImage.fill(QtGui.QColor(255, 255, 255))
            # Works in older Qt4 versions
            self.legend_image.fill(255 + 255 * 256 + 255 * 256 * 256)
            painter = QtGui.QPainter(self.legend_image)
            font_weight = QtGui.QFont.Bold
            italics_flag = False
            font = QtGui.QFont(
                'verdana', self.legend_font_size, font_weight, italics_flag)
            painter.setFont(font)
            painter.drawText(10, 25, self.legend_title)

            if self.legend_units is not None:
                font_weight = QtGui.QFont.StyleNormal
                italics_flag = True
                legend_units_font_size = self.legend_font_size / 2
                font = QtGui.QFont(
                    'verdana',
                    legend_units_font_size,
                    font_weight,
                    italics_flag)
                painter.setFont(font)
                painter.drawText(10, 45, self.legend_units)

        else:
            # extend the existing legend down for the next class
            image = QtGui.QImage(
                self.legend_width,
                self.legend_image.height() + self.legend_increment,
                QtGui.QImage.Format_RGB32)
            image.setDotsPerMeterX(dpi_to_meters(self.dpi))
            image.setDotsPerMeterY(dpi_to_meters(self.dpi))
            # Only works in Qt4.8
            #myImage.fill(QtGui.qRgb(255, 255, 255))
            # Works in older Qt4 versions
            image.fill(255 + 255 * 256 + 255 * 256 * 256)
            painter = QtGui.QPainter(image)

            rect = QtCore.QRectF(
                0, 0, self.legend_image.width(), self.legend_image.height())
            painter.drawImage(rect, self.legend_image, rect)
            self.legend_image = image
Example #7
0
    def grow_legend(self):
        """Grow the legend pixmap enough to accommodate one more legend entry.
        """
        LOGGER.debug('InaSAFE Map Legend extendLegend called')
        if self.legend_image is None:

            self.legend_image = QtGui.QImage(self.legend_width, 95,
                                             QtGui.QImage.Format_RGB32)
            self.legend_image.setDotsPerMeterX(dpi_to_meters(self.dpi))
            self.legend_image.setDotsPerMeterY(dpi_to_meters(self.dpi))

            # Only works in Qt4.8
            # self.legendImage.fill(QtGui.QColor(255, 255, 255))
            # Works in older Qt4 versions
            self.legend_image.fill(255 + 255 * 256 + 255 * 256 * 256)
            painter = QtGui.QPainter(self.legend_image)
            font_weight = QtGui.QFont.Bold
            italics_flag = False
            font = QtGui.QFont('verdana', self.legend_font_size, font_weight,
                               italics_flag)
            painter.setFont(font)
            painter.drawText(10, 25, self.legend_title)

            if self.legend_units is not None:
                font_weight = QtGui.QFont.StyleNormal
                italics_flag = True
                legend_units_font_size = self.legend_font_size / 2
                font = QtGui.QFont('verdana', legend_units_font_size,
                                   font_weight, italics_flag)
                painter.setFont(font)
                painter.drawText(10, 45, self.legend_units)

        else:
            # extend the existing legend down for the next class
            image = QtGui.QImage(
                self.legend_width,
                self.legend_image.height() + self.legend_increment,
                QtGui.QImage.Format_RGB32)
            image.setDotsPerMeterX(dpi_to_meters(self.dpi))
            image.setDotsPerMeterY(dpi_to_meters(self.dpi))
            # Only works in Qt4.8
            # myImage.fill(QtGui.qRgb(255, 255, 255))
            # Works in older Qt4 versions
            image.fill(255 + 255 * 256 + 255 * 256 * 256)
            painter = QtGui.QPainter(image)

            rect = QtCore.QRectF(0, 0, self.legend_image.width(),
                                 self.legend_image.height())
            painter.drawImage(rect, self.legend_image, rect)
            self.legend_image = image
Example #8
0
    def grow_legend(self):
        """Grow the legend pixmap enough to accommodate one more legend entry.
        """
        LOGGER.debug('InaSAFE Map Legend extendLegend called')
        if self.legendImage is None:

            self.legendImage = QtGui.QImage(self.legendWidth, 95,
                                            QtGui.QImage.Format_RGB32)
            self.legendImage.setDotsPerMeterX(dpi_to_meters(self.dpi))
            self.legendImage.setDotsPerMeterY(dpi_to_meters(self.dpi))

            # Only works in Qt4.8
            #self.legendImage.fill(QtGui.QColor(255, 255, 255))
            # Works in older Qt4 versions
            self.legendImage.fill(255 + 255 * 256 + 255 * 256 * 256)
            myPainter = QtGui.QPainter(self.legendImage)
            myFontWeight = QtGui.QFont.Bold
            myItalicsFlag = False
            myFont = QtGui.QFont('verdana', self.legendFontSize, myFontWeight,
                                 myItalicsFlag)
            myPainter.setFont(myFont)
            myPainter.drawText(10, 25, self.legendTitle)

            if self.legendUnits is not None:
                myFontWeight = QtGui.QFont.StyleNormal
                myItalicsFlag = True
                legendUnitsFontSize = self.legendFontSize / 2
                myFont = QtGui.QFont('verdana', legendUnitsFontSize,
                                     myFontWeight, myItalicsFlag)
                myPainter.setFont(myFont)
                myPainter.drawText(10, 45, self.legendUnits)

        else:
            # extend the existing legend down for the next class
            myImage = QtGui.QImage(
                self.legendWidth,
                self.legendImage.height() + self.legendIncrement,
                QtGui.QImage.Format_RGB32)
            myImage.setDotsPerMeterX(dpi_to_meters(self.dpi))
            myImage.setDotsPerMeterY(dpi_to_meters(self.dpi))
            # Only works in Qt4.8
            #myImage.fill(QtGui.qRgb(255, 255, 255))
            # Works in older Qt4 versions
            myImage.fill(255 + 255 * 256 + 255 * 256 * 256)
            myPainter = QtGui.QPainter(myImage)

            myRect = QtCore.QRectF(0, 0, self.legendImage.width(),
                                   self.legendImage.height())
            myPainter.drawImage(myRect, self.legendImage, myRect)
            self.legendImage = myImage
Example #9
0
 def testDpiToMeters(self):
     """Test conversion from dpi to dpm."""
     myDpi = 300
     myDpm = dpi_to_meters(myDpi)
     myExpectedDpm = 11811.023622
     myMessage = ('Conversion from dpi to dpm failed\n'
                  ' Got: %s Expected: %s\n' % (myDpm, myExpectedDpm))
     self.assertAlmostEqual(myDpm, myExpectedDpm, msg=myMessage)
Example #10
0
 def test_dpi_to_meters(self):
     """Test conversion from dpi to dpm."""
     dpi = 300
     dpm = dpi_to_meters(dpi)
     expected_dpm = 11811.023622
     message = ('Conversion from dpi to dpm failed\n'
                ' Got: %s Expected: %s\n' % (dpm, expected_dpm))
     self.assertAlmostEqual(dpm, expected_dpm, msg=message)
Example #11
0
 def testDpiToMeters(self):
     """Test conversion from dpi to dpm."""
     myDpi = 300
     myDpm = dpi_to_meters(myDpi)
     myExpectedDpm = 11811.023622
     myMessage = ('Conversion from dpi to dpm failed\n'
                  ' Got: %s Expected: %s\n' %
                  (myDpm, myExpectedDpm))
     self.assertAlmostEqual(myDpm, myExpectedDpm, msg=myMessage)
Example #12
0
    def html_to_image(self, html, width_mm):
        """Render some HTML to a pixmap.

        :param html: HTML to be rendered. It is assumed that the html
              is a snippet only, containing no body element - a standard
              header and footer will be appended.
        :type html: str

        :param width_mm: width of the table in mm - will be converted to
              points based on the resolution of our page.
        :type width_mm: int

        :returns: An image containing the rendered html.
        :rtype: QImage
        """
        LOGGER.debug('InaSAFE Map renderHtmlToImage called')

        width_px = mm_to_points(width_mm, self.page_dpi)
        self.load_and_wait(html_snippet=html)
        frame = self.web_view.page().mainFrame()

        # Using 150dpi as the baseline, work out a standard text size
        # multiplier so that page renders equally well at different print
        # resolutions.
        #myBaselineDpi = 150
        #myFactor = float(self.page_dpi) / myBaselineDpi
        #myFrame.setTextSizeMultiplier(myFactor)

        size = frame.contentsSize()
        size.setWidth(width_px)
        self.web_view.page().setViewportSize(size)

        image = QtGui.QImage(size, QtGui.QImage.Format_RGB32)
        image.setDotsPerMeterX(dpi_to_meters(self.page_dpi))
        image.setDotsPerMeterY(dpi_to_meters(self.page_dpi))
        # Only works in Qt4.8
        #image.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        image.fill(255 + 255 * 256 + 255 * 256 * 256)
        painter = QtGui.QPainter(image)
        frame.render(painter)
        painter.end()

        return image
Example #13
0
    def html_to_image(self, html, width_mm):
        """Render some HTML to a pixmap.

        :param html: HTML to be rendered. It is assumed that the html
              is a snippet only, containing no body element - a standard
              header and footer will be appended.
        :type html: str

        :param width_mm: width of the table in mm - will be converted to
              points based on the resolution of our page.
        :type width_mm: int

        :returns: An image containing the rendered html.
        :rtype: QImage
        """
        LOGGER.debug('InaSAFE Map renderHtmlToImage called')

        myWidthPx = mm_to_points(width_mm, self.pageDpi)
        self.load_and_wait(html_snippet=html)
        myFrame = self.webView.page().mainFrame()

        # Using 150dpi as the baseline, work out a standard text size
        # multiplier so that page renders equally well at different print
        # resolutions.
        #myBaselineDpi = 150
        #myFactor = float(self.page_dpi) / myBaselineDpi
        #myFrame.setTextSizeMultiplier(myFactor)

        mySize = myFrame.contentsSize()
        mySize.setWidth(myWidthPx)
        self.webView.page().setViewportSize(mySize)

        myImage = QtGui.QImage(mySize, QtGui.QImage.Format_RGB32)
        myImage.setDotsPerMeterX(dpi_to_meters(self.pageDpi))
        myImage.setDotsPerMeterY(dpi_to_meters(self.pageDpi))
        # Only works in Qt4.8
        #myImage.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        myImage.fill(255 + 255 * 256 + 255 * 256 * 256)
        myPainter = QtGui.QPainter(myImage)
        myFrame.render(myPainter)
        myPainter.end()
        myImage.save('/tmp/test.png')
        return myImage
Example #14
0
    def renderHtmlToImage(self, theHtml, theWidthMM):
        """Render some HTML to a pixmap.

        Args:
            * theHtml - HTML to be rendered. It is assumed that the html
              is a snippet only, containing no body element - a standard
              header and footer will be appended.
            * theWidthMM- width of the table in mm - will be converted to
              points based on the resolution of our page.
        Returns:
            QImage
        Raises:
            Any exceptions raised by the InaSAFE library will be propagated.
        """
        LOGGER.debug('InaSAFE Map renderHtmlToImage called')

        myWidthPx = mm_to_points(theWidthMM, self.pageDpi)
        self.loadAndWait(theHtmlSnippet=theHtml)
        myFrame = self.webView.page().mainFrame()

        # Using 150dpi as the baseline, work out a standard text size
        # multiplier so that page renders equally well at different print
        # resolutions.
        #myBaselineDpi = 150
        #myFactor = float(self.pageDpi) / myBaselineDpi
        #myFrame.setTextSizeMultiplier(myFactor)

        mySize = myFrame.contentsSize()
        mySize.setWidth(myWidthPx)
        self.webView.page().setViewportSize(mySize)

        myImage = QtGui.QImage(mySize, QtGui.QImage.Format_RGB32)
        myImage.setDotsPerMeterX(dpi_to_meters(self.pageDpi))
        myImage.setDotsPerMeterY(dpi_to_meters(self.pageDpi))
        # Only works in Qt4.8
        #myImage.fill(QtGui.qRgb(255, 255, 255))
        # Works in older Qt4 versions
        myImage.fill(255 + 255 * 256 + 255 * 256 * 256)
        myPainter = QtGui.QPainter(myImage)
        myFrame.render(myPainter)
        myPainter.end()
        myImage.save('/tmp/test.png')
        return myImage
Example #15
0
 def test_dpi_to_meters(self):
     """Test conversion from dpi to dpm."""
     dpi = 300
     dpm = dpi_to_meters(dpi)
     expected_dpm = 11811.023622
     message = (
         'Conversion from dpi to dpm failed\n'
         ' Got: %s Expected: %s\n' %
         (dpm, expected_dpm))
     self.assertAlmostEqual(dpm, expected_dpm, msg=message)