Example #1
0
 def testAsWktPolygon(self):
     """Test that we can get a proper rect wkt polygon representation for rect"""
     rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
     myExpectedWkt = "POLYGON((0 0, " "5 0, " "5 5, " "0 5, " "0 0))"
     myWkt = rect1.asWktPolygon()
     myMessage = "Expected: %s\nGot: %s\n" % (myExpectedWkt, myWkt)
     assert compareWkt(myWkt, myExpectedWkt), myMessage
    def test_mouse_drag(self):
        """Test setting extents by dragging works.

        This currently fails as QTest does not properly do the mouse
        interactions with the canvas.

        """
        # Imported here because it is not available in OSX QGIS bundle
        # pylint: disable=redefined-outer-name
        from PyQt4.QtTest import QTest

        # Click the capture button
        QTest.mouseClick(self.dialog.capture_button, Qt.LeftButton)

        # drag a rect on the canvas
        QTest.mousePress(CANVAS, Qt.LeftButton, pos=QPoint(0, 0), delay=500)
        QTest.mouseRelease(
            CANVAS, Qt.LeftButton,
            pos=QPoint(300, 300),
            delay=-1)

        # on drag the extents selector windows should appear again
        QTest.qWaitForWindowShown(self.dialog)
        # Click ok to dispose of the window again
        ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok)
        QTest.mouseClick(ok, Qt.LeftButton)

        # Check the extent emitted on closing teh dialog is correct
        expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0)
        self.assertEqual(self.extent.toString(), expected_extent.toString())
    def update_extent(self, extent):
        """Update extent value in GUI based from an extent.

        :param extent: A list in the form [xmin, ymin, xmax, ymax] where all
            coordinates provided are in Geographic / EPSG:4326.
        :type extent: list
        """
        self.x_minimum.setValue(extent[0])
        self.y_minimum.setValue(extent[1])
        self.x_maximum.setValue(extent[2])
        self.y_maximum.setValue(extent[3])

        # Updating the country if possible.
        rectangle = QgsRectangle(extent[0], extent[1], extent[2], extent[3])
        center = rectangle.center()

        for country in self.bbox_countries:
            for polygon in self.bbox_countries[country]:
                if polygon.contains(center):
                    index = self.country_comboBox.findText(country)
                    self.country_comboBox.setCurrentIndex(index)
                    break
            else:
                # Continue if the inner loop wasn't broken.
                continue
            # Inner loop was broken, break the outer.
            break
        else:
            self.country_comboBox.setCurrentIndex(0)
    def getBBox(self, item):
        ogrFeature = item.data(Qt.UserRole)
        geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt())

        if (ogrFeature.GetDefnRef().GetGeomType() == ogr.wkbPoint):
            mapextent = self.plugin.canvas.extent()
            ww = mapextent.width()/100
            mapcrs = self.plugin.canvas.mapSettings().destinationCrs()

            x = geom.boundingBox().center().x()
            y = geom.boundingBox().center().y()

            ww = 50.0
            if mapcrs.mapUnits() == QgsUnitTypes.DistanceFeet:
                ww = 150
            if mapcrs.mapUnits() == QgsUnitTypes.DistanceDegrees:
                ww = 0.0005

            bbox = QgsRectangle(x-10*ww, y-10*ww, x+10*ww, y+10*ww)
            return bbox
        else:
            bbox = geom.boundingBox()
            rubberRect = QgsRectangle(bbox.xMinimum(), bbox.yMinimum(),
                                      bbox.xMaximum(), bbox.yMaximum())
            return rubberRect
Example #5
0
    def initRotation(self, boundBox):
        # calculate rotation parameters..interpreted from affine transformation plugin

        anchorPoint = boundBox.center()
        # We convert the angle from degree to radiant
        rad = self.angle.value() * math.pi / 180.0

        a = math.cos(rad)
        b = -1 * math.sin(rad)
        c = anchorPoint.x() - math.cos(rad) * anchorPoint.x() + math.sin(rad) * anchorPoint.y()
        d = math.sin(rad)
        e = math.cos(rad)
        f = anchorPoint.y() - math.sin(rad) * anchorPoint.x() - math.cos(rad) * anchorPoint.y()

        self.rotationParams = (a, b, c, d, e, f)

        # Rotate the bounding box to set a new extent
        ptMin = QgsPoint(boundBox.xMinimum(), boundBox.yMinimum())
        ptMax = QgsPoint(boundBox.xMaximum(), boundBox.yMaximum())

        self.rotatePoint(ptMin)
        self.rotatePoint(ptMax)

        newBoundBox = QgsRectangle(ptMin, ptMax)
        newBoundBox.combineExtentWith(boundBox)

        return newBoundBox
Example #6
0
 def testAsWktCoordinates(self):
     """Test that we can get a proper wkt representation fo the rect"""
     rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
     myExpectedWkt = "0 0, " "5 5"
     myWkt = rect1.asWktCoordinates()
     myMessage = "Expected: %s\nGot: %s\n" % (myExpectedWkt, myWkt)
     assert compareWkt(myWkt, myExpectedWkt), myMessage
    def bounds(self):
        """
        Function for recalculating the bounded extents of the
        layers as they are processed. Under construction
        :return:
        """
        # Requires refinement for raster manipulation of bounds
        selected_extent = unicode(self.getParameterValue(self.MAP_EXTENT)).split(',')

        xMin = float(selected_extent[0])
        xMax = float(selected_extent[1])
        yMin = float(selected_extent[2])
        yMax = float(selected_extent[3])
        extent = QgsRectangle(xMin, yMin, xMax, yMax)

        mapCRS = iface.mapCanvas().mapSettings().destinationCrs()
        transform = QgsCoordinateTransform(
            mapCRS,
            QgsCoordinateReferenceSystem('EPSG:4326')  # WGS84
            # QgsCoordinateReferenceSystem('EPSG:3785')  # Popular vis mercator
        )

        try:
            layer_extent = transform.transform(extent)
        except QgsCsException:
            ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
                                   "exception in transform layer srs")
            layer_extent = QgsRectangle(-180, -90, 180, 90)

        ProcessingLog.addToLog(ProcessingLog.LOG_INFO, layer_extent.toString())

        return layer_extent
Example #8
0
def layer_value(feature, layer, defaultconfig):
    layername = defaultconfig['layer']
    expression = defaultconfig['expression']
    field = defaultconfig['field']

    searchlayer = QgsMapLayerRegistry.instance().mapLayersByName(layername)[0]
    if feature.geometry():
        rect = feature.geometry().boundingBox()
        if layer.geometryType() == QGis.Point:
            point = feature.geometry().asPoint()
            rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10)
        else:
            rect.scale(20)

        rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect)
        rq = QgsFeatureRequest().setFilterRect(rect)\
                                .setFlags(QgsFeatureRequest.ExactIntersect)
        features = searchlayer.getFeatures(rq)
    else:
        features = searchlayer.getFeatures()

    exp = QgsExpression(expression)
    exp.prepare(searchlayer.pendingFields())

    for f in features:
        if exp.evaluate(f):
            return f[field]

    raise DefaultError('No features found')
Example #9
0
    def testOperators(self):
        rect1 = QgsRectangle(10, 20, 40, 40)
        rect2 = rect1 + QgsVector(3, 5.5)
        assert rect2 == QgsRectangle(13, 25.5, 43, 45.5), "QgsRectangle + operator does no work"

        # Subtracting the center point, so it becomes zero.
        rect1 -= rect1.center() - QgsPointXY(0, 0)
        assert rect1.center() == QgsPointXY(0, 0)
 def testAsWktCoordinates(self):
     """Test that we can get a proper wkt representation fo the rect"""
     rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0)
     myExpectedWkt = '0.0000000000000000 0.0000000000000000, 5.0000000000000000 5.0000000000000000'
     myWkt = rect1.asWktCoordinates()
     myMessage = ('Expected: %s\nGot: %s\n' %
                   (myExpectedWkt, myWkt))
     self.assertEquals(myWkt, myExpectedWkt, myMessage)
Example #11
0
  def _rect(self, startPoint, endPoint):
    if startPoint is None or endPoint is None:
      return None

    p0 = self.toCanvasCoordinates(startPoint)
    p1 = self.toCanvasCoordinates(endPoint)
    canvas_rect = QgsRectangle(QgsPoint(p0.x(), p0.y()), QgsPoint(p1.x(), p1.y()))
    center = QgsPoint((startPoint.x() + endPoint.x()) / 2, (startPoint.y() + endPoint.y()) / 2)
    return RotatedRect(center, self.mupp * canvas_rect.width(), self.mupp * canvas_rect.height()).rotate(self.rotation, center)
Example #12
0
    def processAlgorithm(self, progress):
        idx = self.getParameterValue(self.TYPE)
        extent = self.getParameterValue(self.EXTENT).split(',')
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)
        crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

        bbox = QgsRectangle(float(extent[0]), float(extent[2]),
                            float(extent[1]), float(extent[3]))

        width = bbox.width()
        height = bbox.height()
        centerX = bbox.center().x()
        centerY = bbox.center().y()
        originX = centerX - width / 2.0
        originY = centerY - height / 2.0

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: %s/%s' % (hSpacing, vSpacing)))

        if width < hSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Horizontal spacing is too small for the covered area'))

        if height < vSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Vertical spacing is too small for the covered area'))

        if self.TYPES[idx].find('polygon') >= 0:
            geometryType = QGis.WKBPolygon
        else:
            geometryType = QGis.WKBLineString

        fields = [QgsField('left', QVariant.Double, '', 24, 16),
                  QgsField('top', QVariant.Double, '', 24, 16),
                  QgsField('right', QVariant.Double, '', 24, 16),
                  QgsField('bottom', QVariant.Double, '', 24, 16)
                  ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
                                                                     geometryType, crs)

        if idx == 0:
            self._rectangleGridLine(
                writer, width, height, originX, originY, hSpacing, vSpacing)
        elif idx == 1:
            self._rectangleGridPoly(
                writer, width, height, originX, originY, hSpacing, vSpacing)
        elif idx == 2:
            self._diamondGrid(
                writer, width, height, originX, originY, hSpacing, vSpacing)
        elif idx == 3:
            self._hexagonGrid(
                writer, width, height, originX, originY, hSpacing, vSpacing)

        del writer
Example #13
0
 def testToBox3d(self):
     rect = QgsRectangle(0, 0.1, 0.2, 0.3)
     box = rect.toBox3d(0.4, 0.5)
     self.assertEqual(box.xMinimum(), 0.0)
     self.assertEqual(box.yMinimum(), 0.1)
     self.assertEqual(box.zMinimum(), 0.4)
     self.assertEqual(box.xMaximum(), 0.2)
     self.assertEqual(box.yMaximum(), 0.3)
     self.assertEqual(box.zMaximum(), 0.5)
Example #14
0
def preview(request, layer_slug):
    """Home page for layers.

    :param request: The web request.
    :param layer_slug: The layer
    """
    layer = get_object_or_404(Layer, slug=layer_slug)

    layer_path = os.path.join(
        settings.MEDIA_ROOT, 'layers', layer.slug, 'raw')
    map_layer = QgsVectorLayer(layer_path, layer.name, 'ogr')
    QgsMapLayerRegistry.instance().addMapLayer(map_layer)
    layer_uri = tempfile.NamedTemporaryFile(
        suffix='.png', prefix='inasafe-web-', dir='/tmp/').name
    # create image
    image = QImage(QSize(100, 100), QImage.Format_ARGB32_Premultiplied)

    # set image's background color
    color = QColor(255, 255, 255)
    image.fill(color.rgb())

    # create painter
    p = QPainter()
    p.begin(image)
    p.setRenderHint(QPainter.Antialiasing)

    renderer = QgsMapRenderer()

    # set layer set
    layers = [map_layer.id()]  # add ID of every layer
    renderer.setLayerSet(layers)

    # set extent
    rect = QgsRectangle(renderer.fullExtent())
    rect.scale(1.1)
    renderer.setExtent(rect)

    # set output size
    renderer.setOutputSize(image.size(), image.logicalDpiX())

    # do the rendering
    renderer.render(p)

    p.end()

    # clean up
    registry_list = qgis_layers()
    QgsMapLayerRegistry.instance().removeMapLayer(map_layer.id())
    print registry_list

    # save image
    image.save(layer_uri, 'png')
    with open(layer_uri, 'rb') as f:
        response = HttpResponse(f.read(), content_type='png')
    os.remove(layer_uri)

    return response
Example #15
0
    def _populate_bookmarks_list(self):
        """Read the sqlite database and populate the bookmarks list.

        If no bookmarks are found, the bookmarks radio button will be disabled
        and the label will be shown indicating that the user should add
        bookmarks in QGIS first.

        Every bookmark are reprojected to mapcanvas crs.
        """
        # Connect to the QGIS sqlite database and check if the table exists.
        # noinspection PyArgumentList
        db_file_path = QgsApplication.qgisUserDatabaseFilePath()
        db = sqlite3.connect(db_file_path)
        cursor = db.cursor()
        cursor.execute(
            'SELECT COUNT(*) '
            'FROM sqlite_master '
            'WHERE type=\'table\' '
            'AND name=\'tbl_bookmarks\';')

        number_of_rows = cursor.fetchone()[0]
        if number_of_rows > 0:
            cursor.execute(
                'SELECT * '
                'FROM tbl_bookmarks;')
            bookmarks = cursor.fetchall()

            canvas_crs = self.canvas.mapSettings().destinationCrs()

            for bookmark in bookmarks:
                name = bookmark[1]
                srid = bookmark[7]
                rectangle = QgsRectangle(
                    bookmark[3], bookmark[4], bookmark[5], bookmark[6])

                if srid != canvas_crs.srsid():
                    transform = QgsCoordinateTransform(
                        QgsCoordinateReferenceSystem(srid),
                        canvas_crs,
                        QgsProject.instance()
                    )
                    try:
                        rectangle = transform.transform(rectangle)
                    except QgsCsException:
                        rectangle = QgsRectangle()

                if rectangle.isEmpty():
                    pass

                self.bookmarks_list.addItem(name, rectangle)
        if self.bookmarks_list.currentIndex() >= 0:
            self.create_bookmarks_label.hide()
        else:
            self.create_bookmarks_label.show()
            self.hazard_exposure_bookmark.setDisabled(True)
            self.bookmarks_list.hide()
 def test_point_to_rectangle(self):
     """Test for point to rectangle."""
     point = QgsPoint(1.0, 1.0)
     rectangle = point_to_rectangle(point)
     expected_rectangle = QgsRectangle(
         0.9999999999900000,
         0.9999999999900000,
         1.0000000000100000,
         1.0000000000100000)
     self.assertEqual(rectangle.toString(), expected_rectangle.toString())
Example #17
0
 def rect(self):
   if self.calculatedRect:
     return self.calculatedRect
   if len(self.quads) == 0:
     return QgsRectangle()
   rect = QgsRectangle(self.quads[0].rect)
   for quad in self.quads[1:]:
     rect.unionRect(quad.rect)
   self.calculatedRect = rect
   return rect
 def testGetClickBbox(self):
     """
     Tests that a click returns a small bbox.
     """
     # pixel coords for fake click
     self.prepareTestCanvas()
     myPoint = QgsPoint(50, 15)
     myBox = self.bucketFill.getClickBbox(myPoint)
     myExpectedBox = QgsRectangle(49.99850465,
                                  14.99850465,
                                  50.00149535,
                                  15.00149535)
     myMessage = ('Bounding box was incorrect. Received values %s'
                  ' Expected values %s' % (
                     str('%s, %s, %s, %s' % (
                         myBox.xMinimum(), myBox.yMinimum(),
                         myBox.xMaximum(), myBox.yMaximum()
                         )),
                     str('%s, %s, %s, %s' % (
                         myExpectedBox.xMinimum(), myExpectedBox.yMinimum(),
                         myExpectedBox.xMaximum(), myExpectedBox.yMaximum()
                         ))
                 ))
     assert (round(myBox.xMinimum(), 9) ==
             round(myExpectedBox.xMinimum(), 9) and
             round(myBox.xMaximum(), 9) ==
             round(myExpectedBox.xMaximum(), 9) and
             round(myBox.yMinimum(), 9) ==
             round(myExpectedBox.yMinimum(), 9) and
             round(myBox.yMaximum(), 9) ==
             round(myExpectedBox.yMaximum(), 9)), myMessage
Example #19
0
    def getClickBbox(self, thePoint):
        """
        Get a tiny bbox around a mouse click.

        Args:
            Point object.
        Returns:
            Tiny QgsRectangle bbox around point.
        Raises:
            CoordinateProcessingException if bbox creation encounters error.
        """

        # get the xy coords
        #QMessageBox.information(None, 'VF', str(thePoint))
        myX = thePoint.x()
        myY = thePoint.y()
        myUnitsPerPixel = self.canvas.mapUnitsPerPixel()

        # create a little bbox from clicked coords
        try:
            myBbox = QgsRectangle()
            myBbox.setXMinimum(myX - myUnitsPerPixel)
            myBbox.setYMinimum(myY - myUnitsPerPixel)
            myBbox.setXMaximum(myX + myUnitsPerPixel)
            myBbox.setYMaximum(myY + myUnitsPerPixel)
            #QMessageBox.information(None, 'VF', myBbox.toString())
            return myBbox
        except:
            msg = 'Click coordinates could not be processed.'
            raise ex.CoordinateProcessingException(msg)
Example #20
0
def layer_value(feature, layer, defaultconfig):
    if not canvas:
        roam.utils.warning("No canvas set for using layer_values default function")
        return None
    layers = []
    # layer name can also be a list of layers to search
    layername = defaultconfig['layer']
    if isinstance(layername, basestring):
        layers.append(layername)
    else:
        layers = layername

    expression = defaultconfig['expression']
    field = defaultconfig['field']

    for searchlayer in layers:
        try:
            searchlayer = QgsMapLayerRegistry.instance().mapLayersByName(searchlayer)[0]
        except IndexError:
            RoamEvents.raisemessage("Missing layer",
                                    "Unable to find layer used in widget expression {}".format(searchlayer),
                                    level=1)
            roam.utils.warning("Unable to find expression layer {}".format(searchlayer))
            return
        if feature.geometry():
            rect = feature.geometry().boundingBox()
            if layer.geometryType() == QGis.Point:
                point = feature.geometry().asPoint()
                rect = QgsRectangle(point.x(), point.y(), point.x() + 10, point.y() + 10)

            rect.scale(20)

            rect = canvas.mapRenderer().mapToLayerCoordinates(layer, rect)
            rq = QgsFeatureRequest().setFilterRect(rect)\
                                    .setFlags(QgsFeatureRequest.ExactIntersect)
            features = searchlayer.getFeatures(rq)
        else:
            features = searchlayer.getFeatures()

        exp = QgsExpression(expression)
        exp.prepare(searchlayer.pendingFields())
        if exp.hasParserError():
            error = exp.parserErrorString()
            roam.utils.warning(error)

        for f in features:
            value = exp.evaluate(f)
            if exp.hasEvalError():
                error = exp.evalErrorString()
                roam.utils.warning(error)
            if value:
                return f[field]

    raise DefaultError('No features found')
Example #21
0
    def processAlgorithm(self, feedback):
        idx = self.getParameterValue(self.TYPE)
        extent = self.getParameterValue(self.EXTENT).split(',')
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)
        hOverlay = self.getParameterValue(self.HOVERLAY)
        vOverlay = self.getParameterValue(self.VOVERLAY)
        crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))

        bbox = QgsRectangle(float(extent[0]), float(extent[2]),
                            float(extent[1]), float(extent[3]))

        width = bbox.width()
        height = bbox.height()
        originX = bbox.xMinimum()
        originY = bbox.yMaximum()

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: %s/%s' % (hSpacing, vSpacing)))

        if width < hSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Horizontal spacing is too small for the covered area'))

        if hSpacing <= hOverlay or vSpacing <= vOverlay:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid overlay: %s/%s' % (hOverlay, vOverlay)))

        if height < vSpacing:
            raise GeoAlgorithmExecutionException(
                self.tr('Vertical spacing is too small for the covered area'))

        fields = [QgsField('left', QVariant.Double, '', 24, 16),
                  QgsField('top', QVariant.Double, '', 24, 16),
                  QgsField('right', QVariant.Double, '', 24, 16),
                  QgsField('bottom', QVariant.Double, '', 24, 16),
                  QgsField('id', QVariant.Int, '', 10, 0)
                  ]

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
                                                                     QgsWkbTypes.Polygon, crs)

        if idx == 0:
            self._rectangleGrid(
                writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
        elif idx == 1:
            self._diamondGrid(
                writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)
        elif idx == 2:
            self._hexagonGrid(
                writer, width, height, originX, originY, hSpacing, vSpacing, hOverlay, vOverlay, feedback)

        del writer
    def test_clip_raster(self):
        """Test we can clip a raster layer."""
        layer = load_test_raster_layer('gisv4', 'hazard', 'earthquake.asc')
        expected = QgsRectangle(106.75, -6.2, 106.80, -6.1)
        new_layer = clip_by_extent(layer, expected)

        extent = new_layer.extent()
        self.assertAlmostEqual(expected.xMinimum(), extent.xMinimum(), 0)
        self.assertAlmostEqual(expected.xMaximum(), extent.xMaximum(), 0)
        self.assertAlmostEqual(expected.yMinimum(), extent.yMinimum(), 0)
        self.assertAlmostEqual(expected.yMaximum(), extent.yMaximum(), 0)
 def testAsWktPolygon(self):
     """Test that we can get a proper wkt polygon representation fo the rect"""
     rect1 = QgsRectangle( 0.0, 0.0, 5.0, 5.0)
     myExpectedWkt = ('POLYGON((0.0000000000000000 0.0000000000000000, '
                      '5.0000000000000000 0.0000000000000000, '
                      '5.0000000000000000 5.0000000000000000, '
                      '0.0000000000000000 5.0000000000000000, '
                      '0.0000000000000000 0.0000000000000000))')
     myWkt = rect1.asWktPolygon()
     myMessage = ('Expected: %s\nGot: %s\n' %
                   (myExpectedWkt, myWkt))
     self.assertEquals(myWkt, myExpectedWkt, myMessage)
Example #24
0
 def testAsWktPolygon(self):
     """Test that we can get a proper rect wkt polygon representation for rect"""
     rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
     myExpectedWkt = ('POLYGON((0 0, '
                      '5 0, '
                      '5 5, '
                      '0 5, '
                      '0 0))')
     myWkt = rect1.asWktPolygon()
     myMessage = ('Expected: %s\nGot: %s\n' %
                  (myExpectedWkt, myWkt))
     assert compareWkt(myWkt, myExpectedWkt), myMessage
    def test_spinboxes(self):
        """Test validate extent method."""
        self.dialog.x_maximum.clear()
        self.dialog.extent_defined.connect(self.extent_defined)
        QTest.mouseClick(self.dialog.x_maximum, Qt.LeftButton)
        QTest.keyClick(self.dialog.x_maximum, '3')
        QTest.keyClick(self.dialog.x_maximum, '0')
        ok = self.dialog.button_box.button(QtGui.QDialogButtonBox.Ok)
        QTest.mouseClick(ok, Qt.LeftButton)

        expected_extent = QgsRectangle(10.0, 10.0, 30.0, 20.0)
        self.assertEqual(self.extent.toString(), expected_extent.toString())
    def _populate_bookmarks_list(self):
        """Read the sqlite database and populate the bookmarks list.

        Every bookmark are reprojected to mapcanvas crs.
        """

        # Connect to the QGIS sqlite database and check if the table exists.
        db_file_path = QgsApplication.qgisUserDbFilePath()
        if not isfile(db_file_path):
            # If the database does not exist.
            return

        try:
            db = sqlite3.connect(db_file_path)
            cursor = db.cursor()
            cursor.execute(
                'SELECT COUNT(*) '
                'FROM sqlite_master '
                'WHERE type=\'table\' '
                'AND name=\'tbl_bookmarks\';')

            number_of_rows = cursor.fetchone()[0]
            if number_of_rows > 0:
                cursor.execute(
                    'SELECT * '
                    'FROM tbl_bookmarks;')
                bookmarks = cursor.fetchall()

                map_renderer = self.canvas.mapRenderer()
                canvas_srid = map_renderer.destinationCrs().srsid()

                for bookmark in bookmarks:
                    name = bookmark[1]
                    srid = bookmark[7]
                    rectangle = QgsRectangle(
                        bookmark[3], bookmark[4], bookmark[5], bookmark[6])

                    if srid != canvas_srid:
                        transform = QgsCoordinateTransform(
                            srid, canvas_srid)
                        rectangle = transform.transform(rectangle)

                    if rectangle.isEmpty():
                        pass

                    self.comboBox_bookmarks_list.addItem(name, rectangle)
        except sqlite3.Error:
            # If we have any SQL error with SQLite.
            return
Example #27
0
    def toSearchRect(self, point):
        searchRadius =  self.canvas.extent().width() * ( self.radius / 100.0 )

        point = self.toMapCoordinates(point)

        rect = QgsRectangle()                                                 
        rect.setXMinimum(point.x() - searchRadius)
        rect.setXMaximum(point.x() + searchRadius)
        rect.setYMinimum(point.y() - searchRadius)
        rect.setYMaximum(point.y() + searchRadius)
        return rect
Example #28
0
 def calculate_layer_extent(self, layer):
     extent = QgsRectangle()
     
     features = layer.getFeatures()
     for feature in features:
         geometry = feature.geometry()
         if extent.isEmpty() :
             extent = geometry.boundingBox()
         else:
             extent.combineExtentWith(geometry.boundingBox())
             
     if extent.isEmpty() :
         extent = layer.extent()
         
     return extent
Example #29
0
 def subdivideRecursively(self, rect, maxHeight):
   if maxHeight <= self.height:
     return
   self.subNodes = []
   for y in range(2):
     for x in range(2):
       xmin = self.rect.xMinimum() + 0.5 * x * self.rect.width()
       ymin = self.rect.yMinimum() + 0.5 * (1 - y) * self.rect.height()
       xmax = xmin + 0.5 * self.rect.width()
       ymax = ymin + 0.5 * self.rect.height()
       quadrect = QgsRectangle(xmin, ymin, xmax, ymax)
       node = QuadNode(self, quadrect, 2 * y + x, self.height + 1)
       self.subNodes.append(node)
       if quadrect.intersects(rect):
         node.subdivideRecursively(rect, maxHeight)
Example #30
0
    def testIntersection(self):
        rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
        rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0)

        myMessage = "Expected: %s\nGot: %s\n" % (True, rect1.intersects(rect2))
        assert rect1.intersects(rect2), myMessage

        rect3 = rect1.intersect(rect2)
        self.assertFalse(rect3.isEmpty(), "Empty rectangle returned")

        myMessage = "Expected: %s\nGot: %s\n" % (3.0, rect3.width())
        assert rect3.width() == 3.0, myMessage

        myMessage = "Expected: %s\nGot: %s\n" % (3.0, rect3.height())
        assert rect3.height() == 3.0, myMessage
Example #31
0
def drawDebugInformation(layer, renderContext, zoom, xmin, ymin, xmax, ymax):
    self = layer
    mapSettings = self.iface.mapCanvas().mapSettings()

    lines = []
    lines.append("TileLayer")
    lines.append(
        " zoom: %d, tile matrix extent: (%d, %d) - (%d, %d), tile count: %d * %d"
        % (zoom, xmin, ymin, xmax, ymax, xmax - xmin, ymax - ymin))

    extent = renderContext.extent()
    lines.append(" map extent (renderContext): %s" % extent.toString())
    lines.append(" map center (renderContext): %lf, %lf" %
                 (extent.center().x(), extent.center().y()))
    lines.append(" map size: %f, %f" % (extent.width(), extent.height()))
    lines.append(" map extent (map canvas): %s" %
                 self.iface.mapCanvas().extent().toString())

    map2pixel = renderContext.mapToPixel()
    painter = renderContext.painter()
    viewport = painter.viewport()
    mapExtent = QgsRectangle(
        map2pixel.toMapCoordinatesF(0, 0),
        map2pixel.toMapCoordinatesF(viewport.width(), viewport.height()))
    lines.append(" map extent (calculated): %s" % mapExtent.toString())
    lines.append(" map center (calc rect): %lf, %lf" %
                 (mapExtent.center().x(), mapExtent.center().y()))

    center = map2pixel.toMapCoordinatesF(0.5 * viewport.width(),
                                         0.5 * viewport.height())
    lines.append(" map center (calc pt): %lf, %lf" % (center.x(), center.y()))

    lines.append(" viewport size (pixel): %d, %d" %
                 (viewport.width(), viewport.height()))
    lines.append(" window size (pixel): %d, %d" %
                 (painter.window().width(), painter.window().height()))
    lines.append(
        " outputSize (pixel): %d, %d" %
        (mapSettings.outputSize().width(), mapSettings.outputSize().height()))

    device = painter.device()
    lines.append(" deviceSize (pixel): %f, %f" %
                 (device.width(), device.height()))
    lines.append(" logicalDpi: %f, %f" %
                 (device.logicalDpiX(), device.logicalDpiY()))
    lines.append(" outputDpi: %f" % mapSettings.outputDpi())
    lines.append(" mapToPixel: %s" % map2pixel.showParameters())

    mupp = map2pixel.mapUnitsPerPixel()
    lines.append(" map units per pixel: %f" % mupp)
    lines.append(" meters per pixel (renderContext): %f" %
                 (extent.width() / viewport.width()))
    transform = renderContext.coordinateTransform()
    if transform:
        mpp = mupp * {
            QGis.Feet: 0.3048,
            QGis.Degrees: self.layerDef.TSIZE1 / 180
        }.get(transform.destCRS().mapUnits(), 1)
        lines.append(" meters per pixel (calc 1): %f" % mpp)

        cx, cy = 0.5 * viewport.width(), 0.5 * viewport.height()
        geometry = QgsGeometry.fromPolyline([
            map2pixel.toMapCoordinatesF(cx - 0.5, cy),
            map2pixel.toMapCoordinatesF(cx + 0.5, cy)
        ])
        geometry.transform(
            QgsCoordinateTransform(
                transform.destCRS(),
                transform.sourceCrs()))  # project CRS to layer CRS (EPSG:3857)
        mpp = geometry.length()
        lines.append(" meters per pixel (calc center pixel): %f" % mpp)

    lines.append(" scaleFactor: %f" % renderContext.scaleFactor())
    lines.append(" rendererScale: %f" % renderContext.rendererScale())

    scaleX, scaleY = self.getScaleToVisibleExtent(renderContext)
    lines.append(" scale: %f, %f" % (scaleX, scaleY))

    # draw information
    textRect = painter.boundingRect(QRect(QPoint(0, 0), viewport.size()),
                                    Qt.AlignLeft, "Q")
    for i, line in enumerate(lines):
        painter.drawText(10, (i + 1) * textRect.height(), line)
        self.log(line)

    # diagonal
    painter.drawLine(
        QPointF(0, 0),
        QPointF(painter.viewport().width(),
                painter.viewport().height()))
    painter.drawLine(QPointF(painter.viewport().width(), 0),
                     QPointF(0,
                             painter.viewport().height()))

    # credit label
    margin, paddingH, paddingV = (3, 4, 3)
    credit = "This is credit"
    rect = QRect(0, 0,
                 painter.viewport().width() - margin,
                 painter.viewport().height() - margin)
    textRect = painter.boundingRect(rect, Qt.AlignBottom | Qt.AlignRight,
                                    credit)
    bgRect = QRect(textRect.left() - paddingH,
                   textRect.top() - paddingV,
                   textRect.width() + 2 * paddingH,
                   textRect.height() + 2 * paddingV)
    painter.drawRect(bgRect)
    painter.drawText(rect, Qt.AlignBottom | Qt.AlignRight, credit)
Example #32
0
class PyProvider(QgsVectorDataProvider):

    next_feature_id = 1

    @classmethod
    def providerKey(cls):
        """Returns the memory provider key"""
        return 'pythonprovider'

    @classmethod
    def description(cls):
        """Returns the memory provider description"""
        return 'Python Test Provider'

    @classmethod
    def createProvider(cls, uri, providerOptions):
        return PyProvider(uri, providerOptions)

    # Implementation of functions from QgsVectorDataProvider

    def __init__(self,
                 uri='',
                 providerOptions=QgsDataProvider.ProviderOptions()):
        super().__init__(uri)
        # Use the memory layer to parse the uri
        mlayer = QgsVectorLayer(uri, 'ml', 'memory')
        self.setNativeTypes(mlayer.dataProvider().nativeTypes())
        self._uri = uri
        self._fields = mlayer.fields()
        self._wkbType = mlayer.wkbType()
        self._features = {}
        self._extent = QgsRectangle()
        self._extent.setMinimal()
        self._subset_string = ''
        self._crs = mlayer.crs()
        self._spatialindex = None
        self._provider_options = providerOptions
        if 'index=yes' in self._uri:
            self.createSpatialIndex()

    def featureSource(self):
        return PyFeatureSource(self)

    def dataSourceUri(self, expandAuthConfig=True):
        return self._uri

    def storageType(self):
        return "Python test memory storage"

    def getFeatures(self, request=QgsFeatureRequest()):
        return QgsFeatureIterator(
            PyFeatureIterator(PyFeatureSource(self), request))

    def uniqueValues(self, fieldIndex, limit=1):
        results = set()
        if fieldIndex >= 0 and fieldIndex < self.fields().count():
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([fieldIndex])
            for f in self.getFeatures(req):
                results.add(f.attributes()[fieldIndex])
        return results

    def wkbType(self):
        return self._wkbType

    def featureCount(self):
        if not self.subsetString():
            return len(self._features)
        else:
            req = QgsFeatureRequest()
            req.setFlags(QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes([])
            return len([f for f in self.getFeatures(req)])

    def fields(self):
        return self._fields

    def addFeatures(self, flist, flags=None):
        added = False
        f_added = []
        for f in flist:
            if f.hasGeometry() and (f.geometry().wkbType() != self.wkbType()):
                return added, f_added

        for f in flist:
            _f = QgsFeature(self.fields())
            _f.setGeometry(f.geometry())
            attrs = [None for i in range(_f.fields().count())]
            for i in range(min(len(attrs), len(f.attributes()))):
                attrs[i] = f.attributes()[i]
            _f.setAttributes(attrs)
            _f.setId(self.next_feature_id)
            self._features[self.next_feature_id] = _f
            self.next_feature_id += 1
            added = True
            f_added.append(_f)

            if self._spatialindex is not None:
                self._spatialindex.insertFeature(_f)

        if len(f_added):
            self.clearMinMaxCache()
            self.updateExtents()

        return added, f_added

    def deleteFeatures(self, ids):
        if not ids:
            return True
        removed = False
        for id in ids:
            if id in self._features:
                if self._spatialindex is not None:
                    self._spatialindex.deleteFeature(self._features[id])
                del self._features[id]
                removed = True
        if removed:
            self.clearMinMaxCache()
            self.updateExtents()
        return removed

    def addAttributes(self, attrs):
        try:
            for new_f in attrs:
                if new_f.type() not in (QVariant.Int, QVariant.Double,
                                        QVariant.String, QVariant.Date,
                                        QVariant.Time, QVariant.DateTime,
                                        QVariant.LongLong, QVariant.StringList,
                                        QVariant.List):
                    continue
                self._fields.append(new_f)
                for f in self._features.values():
                    old_attrs = f.attributes()
                    old_attrs.append(None)
                    f.setAttributes(old_attrs)
            self.clearMinMaxCache()
            return True
        except Exception:
            return False

    def renameAttributes(self, renamedAttributes):
        result = True
        # We need to replace all fields because python bindings return a copy from [] and at()
        new_fields = [self._fields.at(i) for i in range(self._fields.count())]
        for fieldIndex, new_name in renamedAttributes.items():
            if fieldIndex < 0 or fieldIndex >= self._fields.count():
                result = False
                continue
            if self._fields.indexFromName(new_name) >= 0:
                #field name already in use
                result = False
                continue
            new_fields[fieldIndex].setName(new_name)
        if result:
            self._fields = QgsFields()
            for i in range(len(new_fields)):
                self._fields.append(new_fields[i])
        return result

    def deleteAttributes(self, attributes):
        attrIdx = sorted(attributes, reverse=True)

        # delete attributes one-by-one with decreasing index
        for idx in attrIdx:
            self._fields.remove(idx)
            for f in self._features.values():
                attr = f.attributes()
                del (attr[idx])
                f.setAttributes(attr)
        self.clearMinMaxCache()
        return True

    def changeAttributeValues(self, attr_map):
        for feature_id, attrs in attr_map.items():
            try:
                f = self._features[feature_id]
            except KeyError:
                continue
            for k, v in attrs.items():
                f.setAttribute(k, v)
        self.clearMinMaxCache()
        return True

    def changeGeometryValues(self, geometry_map):
        for feature_id, geometry in geometry_map.items():
            try:
                f = self._features[feature_id]
                f.setGeometry(geometry)
            except KeyError:
                continue
        self.updateExtents()
        return True

    def allFeatureIds(self):
        return list(self._features.keys())

    def subsetString(self):
        return self._subset_string

    def setSubsetString(self, subsetString):
        if subsetString == self._subset_string:
            return True
        self._subset_string = subsetString
        self.updateExtents()
        self.clearMinMaxCache()
        self.dataChanged.emit()
        return True

    def supportsSubsetString(self):
        return True

    def createSpatialIndex(self):
        if self._spatialindex is None:
            self._spatialindex = QgsSpatialIndex()
            for f in self._features:
                self._spatialindex.insertFeature(f)
        return True

    def capabilities(self):
        return QgsVectorDataProvider.AddFeatures | QgsVectorDataProvider.DeleteFeatures | QgsVectorDataProvider.CreateSpatialIndex | QgsVectorDataProvider.ChangeGeometries | QgsVectorDataProvider.ChangeAttributeValues | QgsVectorDataProvider.AddAttributes | QgsVectorDataProvider.DeleteAttributes | QgsVectorDataProvider.RenameAttributes | QgsVectorDataProvider.SelectAtId | QgsVectorDataProvider.CircularGeometries

    #/* Implementation of functions from QgsDataProvider */

    def name(self):
        return self.providerKey()

    def extent(self):
        if self._extent.isEmpty() and self._features:
            self._extent.setMinimal()
            if not self._subset_string:
                # fast way - iterate through all features
                for feat in self._features.values():
                    if feat.hasGeometry():
                        self._extent.combineExtentWith(
                            feat.geometry().boundingBox())
            else:
                for f in self.getFeatures(
                        QgsFeatureRequest().setSubsetOfAttributes([])):
                    if f.hasGeometry():
                        self._extent.combineExtentWith(
                            f.geometry().boundingBox())

        elif not self._features:
            self._extent.setMinimal()
        return QgsRectangle(self._extent)

    def updateExtents(self):
        self._extent.setMinimal()

    def isValid(self):
        return True

    def crs(self):
        return self._crs
Example #33
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr",
                            QgsVectorLayer.LayerOptions(False))
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)

        query = toPercent("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 6)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = toPercent("SELECT * FROM france_parts")
        l5 = QgsVectorLayer(
            "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query,
            "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum([x[0] for x in s]), 10659)
        self.assertEqual(sum([x[1] for x in s]), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]),
                         True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
Example #34
0
    def convert_to_offline(self, db, surveyor_expression_dict, export_dir):
        sys.path.append(PLUGINS_DIR)
        from qfieldsync.core.layer import LayerSource, SyncAction
        from qfieldsync.core.offline_converter import OfflineConverter
        from qfieldsync.core.project import ProjectConfiguration

        project = QgsProject.instance()
        extent = QgsRectangle()
        offline_editing = QgsOfflineEditing()

        # Configure project
        project_configuration = ProjectConfiguration(project)
        project_configuration.create_base_map = False
        project_configuration.offline_copy_only_aoi = False
        project_configuration.use_layer_selection = True

        # Layer config
        layer_sync_action = LayerConfig.get_field_data_capture_layer_config(
            db.names)

        total_projects = len(surveyor_expression_dict)
        current_progress = 0

        for surveyor, layer_config in surveyor_expression_dict.items():
            export_folder = os.path.join(export_dir, surveyor)

            # Get layers (cannot be done out of this for loop because the project is closed and layers are deleted)
            layers = {
                layer_name: None
                for layer_name, _ in layer_sync_action.items()
            }
            self.app.core.get_layers(db, layers, True)
            if not layers:
                return False, QCoreApplication.translate(
                    "FieldDataCapture",
                    "At least one layer could not be found.")

            # Configure layers
            for layer_name, layer in layers.items():
                layer_source = LayerSource(layer)
                layer_source.action = layer_sync_action[layer_name]
                if layer_name in layer_config:
                    layer_source.select_expression = layer_config[layer_name]
                layer_source.apply()

            offline_converter = OfflineConverter(project, export_folder,
                                                 extent, offline_editing)
            offline_converter.convert()
            offline_editing.layerProgressUpdated.disconnect(
                offline_converter.on_offline_editing_next_layer)
            offline_editing.progressModeSet.disconnect(
                offline_converter.on_offline_editing_max_changed)
            offline_editing.progressUpdated.disconnect(
                offline_converter.offline_editing_task_progress)

            current_progress += 1
            self.total_progress_updated.emit(
                int(100 * current_progress / total_projects))

        return True, QCoreApplication.translate(
            "FieldDataCapture",
            "{count} offline projects have been successfully created in <a href='file:///{normalized_path}'>{path}</a>!"
        ).format(count=total_projects,
                 normalized_path=normalize_local_url(export_dir),
                 path=export_dir)
        def run_checks():
            self.assertEqual([f.name() for f in vl.fields()],
                             ['fid', 'type', 'value'])

            # expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16")
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fid
            req = QgsFeatureRequest()
            req.setFilterFid(5)
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fids
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # check with subset of attributes
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            req.setSubsetOfAttributes([2])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes()[2], 16)
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16 or value=14")
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and fids
            req = QgsFeatureRequest()
            req.setFilterFids([3, 5])
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed
            req = QgsFeatureRequest()
            req.setSubsetOfAttributes([])
            it = vl.getFeatures(req)
            ids = []
            geoms = {}
            while it.nextFeature(f):
                ids.append(f.id())
                geoms[f.id()] = f.geometry().asWkt()
            self.assertCountEqual(ids, [3, 4, 5])
            self.assertEqual(geoms, {
                3: 'Point (3 3)',
                4: 'Point (4 4)',
                5: 'Point (5 5)'
            })
Example #36
0
    def testSubsetString(self):
        if not self.source.supportsSubsetString():
            print('Provider does not support subset strings')
            return

        subset = self.getSubsetString()
        self.source.setSubsetString(subset)
        self.assertEqual(self.source.subsetString(), subset)
        result = set([f['pk'] for f in self.source.getFeatures()])
        all_valid = (all(f.isValid() for f in self.source.getFeatures()))
        self.source.setSubsetString(None)

        expected = set([2, 3, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter rect
        self.source.setSubsetString(subset)
        extent = QgsRectangle(-70, 70, -60, 75)
        request = QgsFeatureRequest().setFilterRect(extent)
        result = set([f['pk'] for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([2])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)

        # Subset string AND filter rect, version 2
        self.source.setSubsetString(subset)
        extent = QgsRectangle(-71, 65, -60, 80)
        result = set([
            f['pk'] for f in self.source.getFeatures(
                QgsFeatureRequest().setFilterRect(extent))
        ])
        self.source.setSubsetString(None)
        expected = set([2, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)

        # Subset string AND expression
        self.source.setSubsetString(subset)
        request = QgsFeatureRequest().setFilterExpression('length("name")=5')
        result = set([f['pk'] for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        self.source.setSubsetString(None)
        expected = set([2, 4])
        assert set(
            expected
        ) == result, 'Expected {} and got {} when testing subset string {}'.format(
            set(expected), result, subset)
        self.assertTrue(all_valid)
Example #37
0
    def testMetadata(self):
        """ Test that metadata is correctly acquired from provider """

        endpoint = self.basetestpath + '/metadata_fake_qgis_http_endpoint'
        with open(sanitize(endpoint, '?f=json'), 'wb') as f:
            f.write("""
        {"currentVersion":10.22,"id":1,"name":"QGIS Test","type":"Feature Layer","description":
        "QGIS Provider Test Layer","geometryType":"esriGeometryPoint","copyrightText":"not copyright","parentLayer":{"id":2,"name":"QGIS Tests"},"subLayers":[],
        "minScale":72225,"maxScale":0,
        "defaultVisibility":true,
        "extent":{"xmin":-71.123,"ymin":66.33,"xmax":-65.32,"ymax":78.3,
        "spatialReference":{"wkid":4326,"latestWkid":4326}},
        "hasAttachments":false,"htmlPopupType":"esriServerHTMLPopupTypeAsHTMLText",
        "displayField":"LABEL","typeIdField":null,
        "fields":[{"name":"OBJECTID","type":"esriFieldTypeOID","alias":"OBJECTID","domain":null}],
        "relationships":[],"canModifyLayer":false,"canScaleSymbols":false,"hasLabels":false,
        "capabilities":"Map,Query,Data","maxRecordCount":1000,"supportsStatistics":true,
        "supportsAdvancedQueries":true,"supportedQueryFormats":"JSON, AMF",
        "ownershipBasedAccessControlForFeatures":{"allowOthersToQuery":true},"useStandardizedQueries":true}"""
                    .encode('UTF-8'))

        with open(
                sanitize(
                    endpoint,
                    '/query?f=json_where=OBJECTID=OBJECTID_returnIdsOnly=true'
                ), 'wb') as f:
            f.write("""
        {
         "objectIdFieldName": "OBJECTID",
         "objectIds": [
          1
         ]
        }
        """.encode('UTF-8'))

        # Create test layer
        vl = QgsVectorLayer("url='http://" + endpoint + "' crs='epsg:4326'",
                            'test', 'arcgisfeatureserver')
        self.assertTrue(vl.isValid())

        extent = QgsLayerMetadata.Extent()
        extent1 = QgsLayerMetadata.SpatialExtent()
        extent1.extentCrs = QgsCoordinateReferenceSystem.fromEpsgId(4326)
        extent1.bounds = QgsBox3d(QgsRectangle(-71.123, 66.33, -65.32, 78.3))
        extent.setSpatialExtents([extent1])
        self.assertEqual(vl.metadata().extent(), extent)

        self.assertEqual(vl.metadata().crs(),
                         QgsCoordinateReferenceSystem.fromEpsgId(4326))
        self.assertEqual(vl.metadata().identifier(),
                         'http://' + sanitize(endpoint, ''))
        self.assertEqual(vl.metadata().parentIdentifier(),
                         'http://' + self.basetestpath + '/2')
        self.assertEqual(vl.metadata().type(), 'dataset')
        self.assertEqual(vl.metadata().abstract(), 'QGIS Provider Test Layer')
        self.assertEqual(vl.metadata().title(), 'QGIS Test')
        self.assertEqual(vl.metadata().rights(), ['not copyright'])
        l = QgsLayerMetadata.Link()
        l.name = 'Source'
        l.type = 'WWW:LINK'
        l.url = 'http://' + sanitize(endpoint, '')
        self.assertEqual(vl.metadata().links(), [l])
Example #38
0
    def testMapTheme(self):
        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)

        layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                               "layer", "memory")
        # add a polygon to layer
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#ffb200'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer.setRenderer(renderer)

        canvas.setLayers([layer])
        canvas.setExtent(QgsRectangle(10, 30, 20, 35))
        canvas.show()

        # need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
        while not canvas.isDrawing():
            app.processEvents()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add some styles
        layer.styleManager().addStyleFromLayer('style1')
        sym2 = QgsFillSymbol.createSimple({'color': '#00b2ff'})
        renderer2 = QgsSingleSymbolRenderer(sym2)
        layer.setRenderer(renderer2)
        layer.styleManager().addStyleFromLayer('style2')

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        layer.styleManager().setCurrentStyle('style1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # OK, so all good with setting/rendering map styles
        # try setting canvas to a particular theme

        # make some themes...
        theme1 = QgsMapThemeCollection.MapThemeRecord()
        record1 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record1.currentStyle = 'style1'
        record1.usingCurrentStyle = True
        theme1.setLayerRecords([record1])

        theme2 = QgsMapThemeCollection.MapThemeRecord()
        record2 = QgsMapThemeCollection.MapThemeLayerRecord(layer)
        record2.currentStyle = 'style2'
        record2.usingCurrentStyle = True
        theme2.setLayerRecords([record2])

        QgsProject.instance().mapThemeCollection().insert('theme1', theme1)
        QgsProject.instance().mapThemeCollection().insert('theme2', theme2)

        canvas.setTheme('theme2')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme2', 'theme2', canvas))

        canvas.setTheme('theme1')
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add another layer
        layer2 = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                                "layer2", "memory")
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer2.dataProvider().addFeatures([f]))

        # create a style
        sym1 = QgsFillSymbol.createSimple({'color': '#b2ff00'})
        renderer = QgsSingleSymbolRenderer(sym1)
        layer2.setRenderer(renderer)

        # rerender canvas - should NOT show new layer
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))
        # test again - this time refresh all layers
        canvas.refreshAllLayers()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme1', 'theme1', canvas))

        # add layer 2 to theme1
        record3 = QgsMapThemeCollection.MapThemeLayerRecord(layer2)
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        # change the appearance of an active style
        layer2.styleManager().addStyleFromLayer('original')
        layer2.styleManager().addStyleFromLayer('style4')
        record3.currentStyle = 'style4'
        record3.usingCurrentStyle = True
        theme1.setLayerRecords([record3])
        QgsProject.instance().mapThemeCollection().update('theme1', theme1)

        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme3', 'theme3', canvas))

        layer2.styleManager().setCurrentStyle('style4')
        sym3 = QgsFillSymbol.createSimple({'color': '#b200b2'})
        layer2.renderer().setSymbol(sym3)
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # try setting layers while a theme is in place
        canvas.setLayers([layer])
        canvas.refresh()

        # should be no change... setLayers should be ignored if canvas is following a theme!
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # setLayerStyleOverrides while theme is in place
        canvas.setLayerStyleOverrides({layer2.id(): 'original'})
        # should be no change... setLayerStyleOverrides should be ignored if canvas is following a theme!
        canvas.refresh()
        canvas.waitWhileRendering()
        self.assertTrue(self.canvasImageCheck('theme4', 'theme4', canvas))

        # clear theme
        canvas.setTheme('')
        canvas.refresh()
        canvas.waitWhileRendering()
        # should be different - we should now render project layers
        self.assertFalse(self.canvasImageCheck('theme4', 'theme4', canvas))
Example #39
0
    def testUnion(self):
        rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
        rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0)
        pnt1 = QgsPointXY(6.0, 2.0)

        rect1.combineExtentWith(rect2)
        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2)))
        assert rect1.contains(rect2), myMessage

        print((rect1.toString()))
        assert rect1 == QgsRectangle(
            0.0, 0.0, 7.0, 7.0), 'Wrong combine with rectangle result'

        rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
        rect1.combineExtentWith(6.0, 2.0)
        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(pnt1)))
        assert rect1.contains(pnt1), myMessage

        myExpectedResult = QgsRectangle(0.0, 0.0, 6.0, 5.0).toString()
        myResult = rect1.toString()
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedResult, myResult))
        self.assertEqual(myResult, myExpectedResult, myMessage)

        rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
        rect1.combineExtentWith(rect2)
        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect2)))
        assert rect1.contains(rect2), myMessage

        assert rect1 == QgsRectangle(0.0, 0.0, 7.0, 7.0), "Wrong union result"
Example #40
0
    def testToString(self):
        """Test the different string representations"""
        self.assertEqual(QgsRectangle().toString(), 'Empty')
        rect = QgsRectangle(0, 0.1, 0.2, 0.3)
        myExpectedString = '0.0000000000000000,0.1000000000000000 : 0.2000000000000000,0.3000000000000000'
        myString = rect.toString()
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        # can't test the actual result here, because floating point inaccuracies mean the result is unpredictable
        # at this precision
        self.assertEqual(len(rect.toString(20)), 93)

        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        myExpectedString = '0,0 : 0,0'
        myString = rect.toString(0)
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        myExpectedString = '0.00,0.10 : 0.20,0.30'
        myString = rect.toString(2)
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        myExpectedString = '0.0,0.1 : 0.2,0.3'
        myString = rect.toString(1)
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        myExpectedString = '0.00,0.10 : 0.20,0.30'
        myString = rect.toString(-1)
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage

        rect = QgsRectangle(5000000.01111, -0.3, 5000000.44111, 99.8)
        myExpectedString = '5000000.01,-0.30 : 5000000.44,99.80'
        myString = rect.toString(-1)
        myMessage = ('Expected: %s\nGot: %s\n' % (myExpectedString, myString))
        assert myString == myExpectedString, myMessage
Example #41
0
    def testDimensions(self):
        rect = QgsRectangle(0.0, 0.0, 10.0, 10.0)

        myMessage = ('Expected: %s\nGot: %s\n' % (10.0, rect.width()))
        assert rect.width() == 10.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (10.0, rect.height()))
        assert rect.height() == 10.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' %
                     ("5.0, 5.0", rect.center().toString()))
        assert rect.center() == QgsPointXY(5.0, 5.0), myMessage

        rect.scale(2.0)

        myMessage = ('Expected: %s\nGot: %s\n' % (20.0, rect.width()))
        assert rect.width() == 20.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (20.0, rect.height()))
        assert rect.height() == 20.0, myMessage
Example #42
0
 def testCalculations(self):
     rect = QgsRectangle(0.0, 1.0, 20.0, 10.0)
     self.assertEqual(rect.area(), 180.0)
     self.assertEqual(rect.perimeter(), 58.0)
Example #43
0
 def testAsPolygon(self):
     """Test string representation as polygon"""
     self.assertEqual(QgsRectangle().asPolygon(), '0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000, 0.00000000 0.00000000')
     self.assertEqual(QgsRectangle(0, 0.1, 0.2, 0.3).asPolygon(), '0.00000000 0.10000000, 0.00000000 0.30000000, 0.20000000 0.30000000, 0.20000000 0.10000000, 0.00000000 0.10000000')
Example #44
0
class GSIElevTileProvider:
    def __init__(self, dest_wkt):
        self.dest_wkt = dest_wkt

        # crs transformer, which aims to calculate bbox in EPSG:3857
        self.crs3857 = QgsCoordinateReferenceSystem(3857)
        self.dest_crs = QgsCoordinateReferenceSystem()
        if not self.dest_crs.createFromWkt(dest_wkt):
            logMessage("Failed to create CRS from WKT: {0}".format(dest_wkt))
        self.transform = QgsCoordinateTransform(self.dest_crs, self.crs3857)

        # approximate bbox of this data
        self.boundingbox = QgsRectangle(13667807, 2320477, 17230031, 5713298)

        self.downloader = Downloader()
        self.downloader.userAgent = "QGIS/{0} Qgis2threejs GSIElevTileProvider".format(
            QGis.QGIS_VERSION)  # not written since QGIS 2.2
        self.downloader.DEFAULT_CACHE_EXPIRATION = QSettings().value(
            "/qgis/defaultTileExpiry", 24, type=int)

        self.driver = gdal.GetDriverByName("MEM")
        self.last_dataset = None

    def name(self):
        return "GSI Elevation Tile"

    def read(self, width, height, extent):
        # calculate bounding box in EPSG:3857
        geometry = extent.geometry()
        geometry.transform(self.transform)
        merc_rect = geometry.boundingBox()

        # if the bounding box doesn't intersect with the bounding box of this
        # data, return a list filled with nodata value
        if not self.boundingbox.intersects(merc_rect):
            return [NODATA_VALUE] * width * height

        # get tiles
        over_smpl = 1
        segments_x = 1 if width == 1 else width - 1
        res = extent.width() / segments_x / over_smpl
        ds = self.getDataset(merc_rect.xMinimum(), merc_rect.yMinimum(),
                             merc_rect.xMaximum(), merc_rect.yMaximum(), res)

        geotransform = extent.geotransform(width, height)
        return self._read(ds, width, height, geotransform)

    def readValue(self, x, y):
        """Get value at the position using 1px * 1px memory raster. The value is calculated using a tile of max zoom level"""
        # coordinate transformation into EPSG:3857
        pt = self.transform.transform(QgsPoint(x, y))

        # if the point is not within the bounding box of this data, return
        # nodata value
        if not self.boundingbox.contains(pt):
            return NODATA_VALUE

        res = 0.1
        hres = res / 2
        ds = self.getDataset(pt.x() - hres,
                             pt.y() - hres,
                             pt.x() + hres,
                             pt.y() + hres, res)

        geotransform = [x - hres, res, 0, y + hres, 0, -res]
        return self._read(ds, 1, 1, geotransform)[0]

    def _read(self, ds, width, height, geotransform):
        # create a memory dataset
        warped_ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32)
        warped_ds.SetProjection(self.dest_wkt)
        warped_ds.SetGeoTransform(geotransform)

        # reproject image
        gdal.ReprojectImage(ds, warped_ds, None, None, gdal.GRA_Bilinear)

        # load values into an array
        band = warped_ds.GetRasterBand(1)
        fs = "f" * width * height
        return struct.unpack(
            fs, band.ReadRaster(0, 0, width, height,
                                buf_type=gdal.GDT_Float32))

    def getDataset(self, xmin, ymin, xmax, ymax, mapUnitsPerPixel):
        # calculate zoom level
        mpp1 = TSIZE1 / TILE_SIZE
        zoom = int(math.ceil(math.log(mpp1 / mapUnitsPerPixel, 2) + 1))
        zoom = max(0, min(zoom, ZMAX))

        # calculate tile range (yOrigin is top)
        size = TSIZE1 / 2**(zoom - 1)
        matrixSize = 2**zoom
        ulx = max(0, int((xmin + TSIZE1) / size))
        uly = max(0, int((TSIZE1 - ymax) / size))
        lrx = min(int((xmax + TSIZE1) / size), matrixSize - 1)
        lry = min(int((TSIZE1 - ymin) / size), matrixSize - 1)

        cols = lrx - ulx + 1
        rows = lry - uly + 1

        # download count limit
        if cols * rows > 128:
            logMessage("Number of tiles to fetch is too large!")
            width = height = 1
            return self.driver.Create("", width, height, 1, gdal.GDT_Float32,
                                      [])

        if self.last_dataset and self.last_dataset[0] == [
                zoom, ulx, uly, lrx, lry
        ]:  # if same as last tile set, return cached dataset
            return self.last_dataset[1]

        urltmpl = "http://cyberjapandata.gsi.go.jp/xyz/dem/{z}/{x}/{y}.txt"
        #urltmpl = "http://localhost/xyz/dem/{z}/{x}/{y}.txt"
        tiles = self.fetchFiles(urltmpl, zoom, ulx, uly, lrx, lry)

        # create a memory dataset
        width = cols * TILE_SIZE
        height = rows * TILE_SIZE
        res = size / TILE_SIZE
        geotransform = [
            ulx * size - TSIZE1, res, 0, TSIZE1 - uly * size, 0, -res
        ]

        #mem_driver = gdal.GetDriverByName("GTiff")
        #ds = mem_driver.Create("D:/fetched_tile.tif", width, height, 1, gdal.GDT_Float32, [])

        ds = self.driver.Create("", width, height, 1, gdal.GDT_Float32, [])
        ds.SetProjection(str(self.crs3857.toWkt()))
        ds.SetGeoTransform(geotransform)

        band = ds.GetRasterBand(1)
        for i, tile in enumerate(tiles):
            if tile:
                col = i % cols
                row = i / cols
                band.WriteRaster(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE,
                                 TILE_SIZE, tile)

        ds.FlushCache()

        self.last_dataset = [[zoom, ulx, uly, lrx, lry], ds]  # cache dataset
        return ds

    def fetchFiles(self, urltmpl, zoom, xmin, ymin, xmax, ymax):
        downloadTimeout = 60

        urls = []
        for y in range(ymin, ymax + 1):
            for x in range(xmin, xmax + 1):
                urls.append(
                    urltmpl.replace("{x}",
                                    str(x)).replace("{y}", str(y)).replace(
                                        "{z}", str(zoom)))
        files = self.downloader.fetchFiles(urls, downloadTimeout)

        for url in urls:
            data = files[url]
            if data:
                # to byte array
                yield numpy.fromstring(data.replace("e",
                                                    str(NODATA_VALUE)).replace(
                                                        "\n", ","),
                                       dtype=numpy.float32,
                                       sep=",").tostring()
            else:
                array = numpy.empty(TILE_SIZE * TILE_SIZE, dtype=numpy.float32)
                array.fill(NODATA_VALUE)
                yield array.tostring()
Example #45
0
    def testRefreshOnTimer(self):
        """ test that map canvas refreshes with auto refreshing layers """
        canvas = QgsMapCanvas()
        canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326))
        canvas.setFrameStyle(0)
        canvas.resize(600, 400)
        self.assertEqual(canvas.width(), 600)
        self.assertEqual(canvas.height(), 400)

        layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string",
                               "layer", "memory")

        canvas.setLayers([layer])
        canvas.setExtent(QgsRectangle(10, 30, 20, 35))
        canvas.show()

        # need to wait until first redraw can occur (note that we first need to wait till drawing starts!)
        while not canvas.isDrawing():
            app.processEvents()
        canvas.waitWhileRendering()
        self.assertTrue(
            self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))

        # add polygon to layer
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer.dataProvider().addFeatures([f]))

        # set auto refresh on layer
        layer.setAutoRefreshInterval(100)
        layer.setAutoRefreshEnabled(True)

        timeout = time.time() + 1
        # expect canvas to auto refresh...
        while not canvas.isDrawing():
            app.processEvents()
            self.assertTrue(time.time() < timeout)
        while canvas.isDrawing():
            app.processEvents()
            self.assertTrue(time.time() < timeout)

        # add a polygon to layer
        f = QgsFeature()
        f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 25, 25, 45)))
        self.assertTrue(layer.dataProvider().addFeatures([f]))
        # wait for canvas auto refresh
        while not canvas.isDrawing():
            app.processEvents()
            self.assertTrue(time.time() < timeout)
        while canvas.isDrawing():
            app.processEvents()
            self.assertTrue(time.time() < timeout)

        # now canvas should look different...
        self.assertFalse(
            self.canvasImageCheck('empty_canvas', 'empty_canvas', canvas))

        # switch off auto refresh
        layer.setAutoRefreshEnabled(False)
        timeout = time.time() + 0.5
        while time.time() < timeout:
            # messy, but only way to check that canvas redraw doesn't occur
            self.assertFalse(canvas.isDrawing())
Example #46
0
    def processAlgorithm(self, parameters, context, feedback):
        rasterPath = self.getParameterValue(self.INPUT_DEM)
        layer = QgsProcessingUtils.mapLayerFromString(
            self.getParameterValue(self.BOUNDARY_LAYER), context)
        step = self.getParameterValue(self.STEP)
        percentage = self.getParameterValue(self.USE_PERCENTAGE)

        outputPath = self.getOutputValue(self.OUTPUT_DIRECTORY)

        rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly)
        geoTransform = rasterDS.GetGeoTransform()
        rasterBand = rasterDS.GetRasterBand(1)
        noData = rasterBand.GetNoDataValue()

        cellXSize = abs(geoTransform[1])
        cellYSize = abs(geoTransform[5])
        rasterXSize = rasterDS.RasterXSize
        rasterYSize = rasterDS.RasterYSize

        rasterBBox = QgsRectangle(geoTransform[0],
                                  geoTransform[3] - cellYSize * rasterYSize,
                                  geoTransform[0] + cellXSize * rasterXSize,
                                  geoTransform[3])
        rasterGeom = QgsGeometry.fromRect(rasterBBox)

        crs = osr.SpatialReference()
        crs.ImportFromProj4(str(layer.crs().toProj4()))

        memVectorDriver = ogr.GetDriverByName('Memory')
        memRasterDriver = gdal.GetDriverByName('MEM')

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0

        for current, f in enumerate(features):
            geom = f.geometry()
            intersectedGeom = rasterGeom.intersection(geom)

            if intersectedGeom.isEmpty():
                feedback.pushInfo(
                    self.tr('Feature {0} does not intersect raster or '
                            'entirely located in NODATA area').format(f.id()))
                continue

            fName = os.path.join(
                outputPath, 'hystogram_%s_%s.csv' % (layer.name(), f.id()))

            ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt())
            bbox = intersectedGeom.boundingBox()
            xMin = bbox.xMinimum()
            xMax = bbox.xMaximum()
            yMin = bbox.yMinimum()
            yMax = bbox.yMaximum()

            (startColumn,
             startRow) = raster.mapToPixel(xMin, yMax, geoTransform)
            (endColumn, endRow) = raster.mapToPixel(xMax, yMin, geoTransform)

            width = endColumn - startColumn
            height = endRow - startRow

            srcOffset = (startColumn, startRow, width, height)
            srcArray = rasterBand.ReadAsArray(*srcOffset)

            if srcOffset[2] == 0 or srcOffset[3] == 0:
                feedback.pushInfo(
                    self.tr('Feature {0} is smaller than raster '
                            'cell size').format(f.id()))
                continue

            newGeoTransform = (geoTransform[0] +
                               srcOffset[0] * geoTransform[1], geoTransform[1],
                               0.0, geoTransform[3] +
                               srcOffset[1] * geoTransform[5], 0.0,
                               geoTransform[5])

            memVDS = memVectorDriver.CreateDataSource('out')
            memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon)

            ft = ogr.Feature(memLayer.GetLayerDefn())
            ft.SetGeometry(ogrGeom)
            memLayer.CreateFeature(ft)
            ft.Destroy()

            rasterizedDS = memRasterDriver.Create('', srcOffset[2],
                                                  srcOffset[3], 1,
                                                  gdal.GDT_Byte)
            rasterizedDS.SetGeoTransform(newGeoTransform)
            gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1])
            rasterizedArray = rasterizedDS.ReadAsArray()

            srcArray = numpy.nan_to_num(srcArray)
            masked = numpy.ma.MaskedArray(
                srcArray,
                mask=numpy.logical_or(srcArray == noData,
                                      numpy.logical_not(rasterizedArray)))

            self.calculateHypsometry(f.id(), fName, feedback, masked,
                                     cellXSize, cellYSize, percentage, step)

            memVDS = None
            rasterizedDS = None
            feedback.setProgress(int(current * total))

        rasterDS = None
Example #47
0
    def testCtor(self):
        rect = QgsRectangle(5.0, 5.0, 10.0, 10.0)

        myExpectedResult = True
        myResult = rect.isEmpty()
        myMessage = ('Expected: %s Got: %s' % (myExpectedResult, myResult))
        assert rect.isEmpty(), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (5.0, rect.xMinimum()))
        assert rect.xMinimum() == 5.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (5.0, rect.yMinimum()))
        assert rect.yMinimum() == 5.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (10.0, rect.xMaximum()))
        assert rect.xMaximum() == 10.0, myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (10.0, rect.yMaximum()))
        assert rect.yMaximum() == 10.0, myMessage
Example #48
0
class DEMBlock:
    def __init__(self, dem_width, dem_height, dem_values, plane_width,
                 plane_height, offsetX, offsetY):
        self.dem_width = dem_width
        self.dem_height = dem_height
        self.dem_values = dem_values
        self.plane_width = plane_width
        self.plane_height = plane_height
        self.offsetX = offsetX
        self.offsetY = offsetY

        self.orig_stats = {"max": max(dem_values), "min": min(dem_values)}
        self.rect = QgsRectangle(offsetX - plane_width * 0.5,
                                 offsetY - plane_height * 0.5,
                                 offsetX + plane_width * 0.5,
                                 offsetY + plane_height * 0.5)

        self.properties = {"width": dem_width, "height": dem_height}
        self.properties["plane"] = {
            "width": plane_width,
            "height": plane_height,
            "offsetX": offsetX,
            "offsetY": offsetY
        }

        self.clip_geometry = None

    def set(self, key, value):
        """set property"""
        self.properties[key] = value

    def setClipGeometry(self, geometry):
        self.clip_geometry = geometry

    def zShift(self, shift):
        if shift != 0:
            self.dem_values = map(lambda x: x + shift, self.dem_values)

    def zScale(self, scale):
        if scale != 1:
            self.dem_values = map(lambda x: x * scale, self.dem_values)

    def write(self, writer):
        mapTo3d = writer.settings.mapTo3d()

        writer.write("bl = lyr.addBlock({0}, {1});\n".format(
            pyobj2js(self.properties), pyobj2js(bool(self.clip_geometry))))
        writer.write("bl.data = [{0}];\n".format(",".join(
            map(gdal2threejs.formatValue, self.dem_values))))

        # clipped with polygon layer
        if self.clip_geometry:
            z_func = lambda x, y: 0
            transform_func = lambda x, y, z: mapTo3d.transform(x, y, z)

            geom = PolygonGeometry.fromQgsGeometry(self.clip_geometry, z_func,
                                                   transform_func)
            geom.splitPolygon(
                writer.triangleMesh(self.dem_width, self.dem_height))

            polygons = []
            for polygon in geom.polygons:
                bnds = []
                for boundary in polygon:
                    bnds.append(map(lambda pt: [pt.x, pt.y], boundary))
                polygons.append(bnds)

            writer.write("bl.clip = {};\n")
            writer.write("bl.clip.polygons = {0};\n".format(
                pyobj2js(polygons)))

            triangles = Triangles()
            polygons = []
            for polygon in geom.split_polygons:
                boundary = polygon[0]
                if len(polygon) == 1 and len(boundary) == 4:
                    # vertex order should be counter-clockwise
                    triangles.addTriangle(boundary[0], boundary[2],
                                          boundary[1])
                else:
                    bnds = [
                        map(lambda pt: [pt.x, pt.y], bnd) for bnd in polygon
                    ]
                    polygons.append(bnds)

            vf = {
                "v": map(lambda pt: [pt.x, pt.y], triangles.vertices),
                "f": triangles.faces
            }
            writer.write("bl.clip.triangles = {0};\n".format(pyobj2js(vf)))
            writer.write("bl.clip.split_polygons = {0};\n".format(
                pyobj2js(polygons)))

    def getValue(self, x, y):
        def _getValue(gx, gy):
            return self.dem_values[gx + self.dem_width * gy]

        if 0 <= x and x <= self.dem_width - 1 and 0 <= y and y <= self.dem_height - 1:
            ix, iy = int(x), int(y)
            sx, sy = x - ix, y - iy

            z11 = _getValue(ix, iy)
            z21 = 0 if x == self.dem_width - 1 else _getValue(ix + 1, iy)
            z12 = 0 if y == self.dem_height - 1 else _getValue(ix, iy + 1)
            z22 = 0 if x == self.dem_width - 1 or y == self.dem_height - \
                1 else _getValue(ix + 1, iy + 1)

            return (1 - sx) * ((1 - sy) * z11 + sy * z12) + sx * \
                ((1 - sy) * z21 + sy * z22)    # bilinear interpolation

        return 0  # as safe null value

    def gridPointToPoint(self, x, y):
        x = self.rect.xMinimum() + self.rect.width() / (self.dem_width - 1) * x
        y = self.rect.yMaximum() - self.rect.height() / (self.dem_height -
                                                         1) * y
        return x, y

    def pointToGridPoint(self, x, y):
        x = (x - self.rect.xMinimum()) / \
            self.rect.width() * (self.dem_width - 1)
        y = (self.rect.yMaximum() - y) / \
            self.rect.height() * (self.dem_height - 1)
        return x, y
Example #49
0
 def testToRectangle(self):
     box = QgsBox3d(5.0, 6.0, 7.0, 11.0, 13.0, 15.0)
     rect = box.toRectangle()
     self.assertEqual(rect, QgsRectangle(5, 6, 11, 13))
Example #50
0
    def testSetOutputCrs(self):
        w = qgis.gui.QgsExtentGroupBox()

        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        w.setCurrentExtent(QgsRectangle(1, 2, 3, 4),
                           QgsCoordinateReferenceSystem('epsg:4326'))
        w.setOutputExtentFromCurrent()
        self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4))

        # with reprojection
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785'))
        self.assertEqual(
            w.outputExtent().toString(4),
            QgsRectangle(111319.4908, 222684.2085, 333958.4724,
                         445640.1097).toString(4))
        # change CRS back
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        # extent should be back to current - not a reprojection of the reprojected bounds
        self.assertEqual(w.outputExtent().toString(20),
                         QgsRectangle(1, 2, 3, 4).toString(20))

        # repeat, this time using original extents
        w = qgis.gui.QgsExtentGroupBox()

        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        w.setOriginalExtent(QgsRectangle(1, 2, 3, 4),
                            QgsCoordinateReferenceSystem('epsg:4326'))
        w.setOutputExtentFromOriginal()
        self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4))

        # with reprojection
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785'))
        self.assertEqual(
            w.outputExtent().toString(4),
            QgsRectangle(111319.4908, 222684.2085, 333958.4724,
                         445640.1097).toString(4))
        # change CRS back
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        # extent should be back to original - not a reprojection of the reprojected bounds
        self.assertEqual(w.outputExtent().toString(20),
                         QgsRectangle(1, 2, 3, 4).toString(20))

        # repeat, this time using layer extent
        layer = QgsVectorLayer("Polygon?crs=4326", 'memory', 'memory')
        self.assertTrue(layer.isValid())
        f = QgsFeature()
        f.setGeometry(
            QgsGeometry.fromWkt('Polygon((1 2, 3 2, 3 4, 1 4, 1 2))'))
        layer.dataProvider().addFeatures([f])
        QgsProject.instance().addMapLayer(layer)
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        w.setOutputExtentFromLayer(layer)
        self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4))

        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785'))
        self.assertEqual(
            w.outputExtent().toString(4),
            QgsRectangle(111319.4908, 222684.2085, 333958.4724,
                         445640.1097).toString(4))
        # change CRS back
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        # extent should be back to original - not a reprojection of the reprojected bounds
        self.assertEqual(w.outputExtent().toString(20),
                         QgsRectangle(1, 2, 3, 4).toString(20))

        # custom extent
        w = qgis.gui.QgsExtentGroupBox()

        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        w.setOutputExtentFromUser(QgsRectangle(1, 2, 3, 4),
                                  QgsCoordinateReferenceSystem('epsg:4326'))
        self.assertEqual(w.outputExtent(), QgsRectangle(1, 2, 3, 4))

        # with reprojection
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:3785'))
        self.assertEqual(
            w.outputExtent().toString(4),
            QgsRectangle(111319.4908, 222684.2085, 333958.4724,
                         445640.1097).toString(4))
        # change CRS back
        w.setOutputCrs(QgsCoordinateReferenceSystem('epsg:4326'))
        # in this case we can't retrieve the original user extent in 4326, so we have a reprojection of the reprojected bounds
        # just test this by restricting the test to 4 decimals
        self.assertEqual(w.outputExtent().toString(4),
                         QgsRectangle(1, 2, 3, 4).toString(4))
Example #51
0
def run(sources_layer_path, receivers_layer_path, emission_pts_layer_path,
        research_ray):
    sources_layer = QgsVectorLayer(sources_layer_path, "input layer", "ogr")
    receivers_layer = QgsVectorLayer(receivers_layer_path, "output layer",
                                     "ogr")

    sources_feat_all = sources_layer.dataProvider().getFeatures()

    receivers_feat_all_dict = {}
    receivers_feat_all = receivers_layer.dataProvider().getFeatures()
    receivers_spIndex = QgsSpatialIndex()
    for receivers_feat in receivers_feat_all:
        receivers_spIndex.insertFeature(receivers_feat)
        receivers_feat_all_dict[receivers_feat.id()] = receivers_feat

    emission_pts_fields = QgsFields()
    emission_pts_fields.append(QgsField("id_emi", QVariant.Int))
    emission_pts_fields.append(QgsField("id_emi_source", QVariant.Int))
    emission_pts_fields.append(QgsField("id_source", QVariant.Int))
    emission_pts_fields.append(
        QgsField("d_rTOe", QVariant.Double, len=10, prec=2))
    # update for QGIS 3 converting VectorWriter to QgsVectorFileWriter
    # emission_pts_writer = VectorWriter(emission_pts_layer_path, None, emission_pts_fields, 0, sources_layer.crs())

    emission_pts_writer = QgsVectorFileWriter(emission_pts_layer_path,
                                              "System", emission_pts_fields,
                                              QgsWkbTypes.Point,
                                              sources_layer.crs(),
                                              "ESRI Shapefile")

    # initializes ray and emission point id
    emission_pt_id = 0

    for sources_feat in sources_feat_all:

        # researches the receiver points in a rectangle created by the research_ray
        # creates the search rectangle
        rect = QgsRectangle()
        rect.setXMinimum(sources_feat.geometry().boundingBox().xMinimum() -
                         research_ray)
        rect.setXMaximum(sources_feat.geometry().boundingBox().xMaximum() +
                         research_ray)
        rect.setYMinimum(sources_feat.geometry().boundingBox().yMinimum() -
                         research_ray)
        rect.setYMaximum(sources_feat.geometry().boundingBox().yMaximum() +
                         research_ray)

        receiver_pts_request = receivers_spIndex.intersects(rect)

        distance_min = []
        for receiver_pts_id in receiver_pts_request:
            receiver_pts_feat = receivers_feat_all_dict[receiver_pts_id]
            result = sources_feat.geometry().closestSegmentWithContext(
                receiver_pts_feat.geometry().asPoint())
            distance_min_tmp = sqrt(result[0])

            if distance_min_tmp <= research_ray:
                distance_min.append(distance_min_tmp)

        # defines segment max length
        if len(distance_min) >= 1:
            segment_max = min(distance_min) / 2
            if segment_max < 2:
                segment_max = 2
        else:
            continue

        # splits the sources line in emission points at a fix distance (minimum distance/2) and create the emission point layer
        # gets vertex
        sources_geom = sources_feat.geometry()
        if sources_geom.isMultipart():
            sources_geom.convertToSingleType()
        sources_feat_vertex_pt_all = sources_geom.asPolyline()

        emission_pt_id_road = 0

        for i in range(0, len(sources_feat_vertex_pt_all)):

            pt1 = QgsPointXY(sources_feat_vertex_pt_all[i])

            add_point_to_layer(emission_pts_writer, pt1, [
                emission_pt_id, emission_pt_id_road,
                sources_feat.id(), segment_max
            ])

            emission_pt_id = emission_pt_id + 1
            emission_pt_id_road = emission_pt_id_road + 1

            if i < len(sources_feat_vertex_pt_all) - 1:

                pt2 = QgsPoint(sources_feat_vertex_pt_all[i + 1])

                x1 = pt1.x()
                y1 = pt1.y()
                x2 = pt2.x()
                y2 = pt2.y()

                if y2 == y1:
                    dx = segment_max
                    dy = 0
                    m = 0
                elif x2 == x1:
                    dx = 0
                    dy = segment_max
                else:
                    m = (y2 - y1) / (x2 - x1)
                    dx = sqrt((segment_max**2) / (1 + m**2))
                    dy = sqrt(((segment_max**2) * (m**2)) / (1 + m**2))

                pt = pt1

                while compute_distance(pt, pt2) > segment_max:
                    x_temp = pt.x()
                    y_temp = pt.y()
                    if x_temp < x2:
                        if m > 0:
                            pt = QgsPointXY(x_temp + dx, y_temp + dy)
                        elif m < 0:
                            pt = QgsPointXY(x_temp + dx, y_temp - dy)
                        elif m == 0:
                            pt = QgsPointXY(x_temp + dx, y_temp)
                    elif x_temp > x2:
                        if m > 0:
                            pt = QgsPointXY(x_temp - dx, y_temp - dy)
                        elif m < 0:
                            pt = QgsPointXY(x_temp - dx, y_temp + dy)
                        elif m == 0:
                            pt = QgsPointXY(x_temp - dx, y_temp)
                    elif x_temp == x2:
                        if y2 > y_temp:
                            pt = QgsPointXY(x_temp, y_temp + dy)
                        else:
                            pt = QgsPointXY(x_temp, y_temp - dy)

                    add_point_to_layer(emission_pts_writer, pt, [
                        emission_pt_id, emission_pt_id_road,
                        sources_feat.id(), segment_max
                    ])

                    emission_pt_id = emission_pt_id + 1
                    emission_pt_id_road = emission_pt_id_road + 1

    del emission_pts_writer
Example #52
0
    def testConvertToMapUnits(self):
        ms = QgsMapSettings()
        ms.setExtent(QgsRectangle(0, 0, 100, 100))
        ms.setOutputSize(QSize(100, 50))
        ms.setOutputDpi(300)
        r = QgsRenderContext.fromMapSettings(ms)

        # renderer scale should be about 1:291937841

        # start with no min/max scale
        c = QgsMapUnitScale()

        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertEqual(size, 2.0)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)

        # minimum size greater than the calculated size, so size should be limited to minSizeMM
        c.minSizeMM = 5
        c.minSizeMMEnabled = True
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 118.1102362, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.minSizeMMEnabled = False

        # maximum size less than the calculated size, so size should be limited to maxSizeMM
        c.maxSizeMM = 0.05
        c.maxSizeMMEnabled = True
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.1811023622047245, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.maxSizeMMEnabled = False

        # test with minimum scale set
        c.minScale = 150000000.0
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 15.57001821, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.minScale = 0

        # test with maximum scale set
        c.maxScale = 1550000000.0
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMapUnits, c)
        self.assertAlmostEqual(size, 1.50677595625, places=5)
        # only conversion from mapunits should be affected
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderMillimeters, c)
        self.assertAlmostEqual(size, 47.244094, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderPoints, c)
        self.assertAlmostEqual(size, 47.2440833, places=5)
        size = r.convertToMapUnits(5.66929, QgsUnitTypes.RenderInches, c)
        self.assertAlmostEqual(size, 3401.574, places=5)
        size = r.convertToMapUnits(2, QgsUnitTypes.RenderPixels, c)
        self.assertAlmostEqual(size, 4.0, places=5)
        c.maxScale = 0
Example #53
0
    def testCase(self):
        self.TEST_DATA_DIR = unitTestDataPath()
        tmppath = tempfile.mkdtemp()
        for file in glob.glob(os.path.join(self.TEST_DATA_DIR, 'france_parts.*')):
            shutil.copy(os.path.join(self.TEST_DATA_DIR, file), tmppath)
        vectorFileInfo = QFileInfo(tmppath + "/france_parts.shp")
        mVectorLayer = QgsVectorLayer(vectorFileInfo.filePath(), vectorFileInfo.completeBaseName(), "ogr")

        QgsProject.instance().addMapLayers([mVectorLayer])
        self.layers = [mVectorLayer]

        # create layout with layout map

        # select epsg:2154
        crs = QgsCoordinateReferenceSystem()
        crs.createFromSrid(2154)
        QgsProject.instance().setCrs(crs)

        self.layout = QgsPrintLayout(QgsProject.instance())
        self.layout.initializeDefaults()

        # fix the renderer, fill with green
        props = {"color": "0,127,0", 'outline_color': 'black'}
        fillSymbol = QgsFillSymbol.createSimple(props)
        renderer = QgsSingleSymbolRenderer(fillSymbol)
        mVectorLayer.setRenderer(renderer)

        # the atlas map
        self.atlas_map = QgsLayoutItemMap(self.layout)
        self.atlas_map.attemptSetSceneRect(QRectF(20, 20, 130, 130))
        self.atlas_map.setFrameEnabled(True)
        self.atlas_map.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.atlas_map)

        # the atlas
        self.atlas = self.layout.atlas()
        self.atlas.setCoverageLayer(mVectorLayer)
        self.atlas.setEnabled(True)

        # an overview
        self.overview = QgsLayoutItemMap(self.layout)
        self.overview.attemptSetSceneRect(QRectF(180, 20, 50, 50))
        self.overview.setFrameEnabled(True)
        self.overview.overview().setLinkedMap(self.atlas_map)
        self.overview.setLayers([mVectorLayer])
        self.layout.addLayoutItem(self.overview)
        nextent = QgsRectangle(49670.718, 6415139.086, 699672.519, 7065140.887)
        self.overview.setExtent(nextent)

        # set the fill symbol of the overview map
        props2 = {"color": "127,0,0,127", 'outline_color': 'black'}
        fillSymbol2 = QgsFillSymbol.createSimple(props2)
        self.overview.overview().setFrameSymbol(fillSymbol2)

        # header label
        self.mLabel1 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel1)
        self.mLabel1.setText("[% \"NAME_1\" %] area")
        self.mLabel1.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel1.adjustSizeToText()
        self.mLabel1.attemptSetSceneRect(QRectF(150, 5, 60, 15))
        self.mLabel1.setMarginX(1)
        self.mLabel1.setMarginY(1)

        # feature number label
        self.mLabel2 = QgsLayoutItemLabel(self.layout)
        self.layout.addLayoutItem(self.mLabel2)
        self.mLabel2.setText("# [%@atlas_featurenumber || ' / ' || @atlas_totalfeatures%]")
        self.mLabel2.setFont(QgsFontUtils.getStandardTestFont())
        self.mLabel2.adjustSizeToText()
        self.mLabel2.attemptSetSceneRect(QRectF(150, 200, 60, 15))
        self.mLabel2.setMarginX(1)
        self.mLabel2.setMarginY(1)

        self.filename_test()
        self.autoscale_render_test()
        self.fixedscale_render_test()
        self.predefinedscales_render_test()
        self.hidden_render_test()
        self.legend_test()
        self.rotation_test()

        shutil.rmtree(tmppath, True)
Example #54
0
 def searchRect(p):
     return QgsRectangle(p.x() - proximity,
                         p.y() - proximity,
                         p.x() + proximity,
                         p.y() + proximity)
    def test_resetSnappingIndex(self):
        self.pointsLayer.setDependencies([])
        self.linesLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])

        ms = QgsMapSettings()
        ms.setOutputSize(QSize(100, 100))
        ms.setExtent(QgsRectangle(0, 0, 1, 1))
        self.assertTrue(ms.hasValidSettings())

        u = QgsSnappingUtils()
        u.setMapSettings(ms)
        cfg = u.config()
        cfg.setEnabled(True)
        cfg.setMode(QgsSnappingConfig.AdvancedConfiguration)
        cfg.setIndividualLayerSettings(self.pointsLayer,
                                       QgsSnappingConfig.IndividualLayerSettings(True,
                                                                                 QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels))
        u.setConfig(cfg)

        m = u.snapToMap(QPoint(95, 100))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(1, 0))

        f = QgsFeature(self.linesLayer.fields())
        f.setId(1)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,1 1)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()

        l1 = len([f for f in self.pointsLayer.getFeatures()])
        self.assertEqual(l1, 4)
        m = u.snapToMap(QPoint(95, 0))
        # snapping not updated
        self.pointsLayer.setDependencies([])
        self.assertEqual(m.isValid(), False)

        # set layer dependencies
        self.pointsLayer.setDependencies([QgsMapLayerDependency(self.linesLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(2)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0,0.5 0.5)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the snapped point is OK
        m = u.snapToMap(QPoint(45, 50))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.5, 0.5))
        self.pointsLayer.setDependencies([])

        # test chained layer dependencies A -> B -> C
        cfg.setIndividualLayerSettings(self.pointsLayer2,
                                       QgsSnappingConfig.IndividualLayerSettings(True,
                                                                                 QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels))
        u.setConfig(cfg)
        self.pointsLayer.setDependencies([QgsMapLayerDependency(self.linesLayer.id())])
        self.pointsLayer2.setDependencies([QgsMapLayerDependency(self.pointsLayer.id())])
        # add another line
        f = QgsFeature(self.linesLayer.fields())
        f.setId(3)
        geom = QgsGeometry.fromWkt("LINESTRING(0 0.2,0.5 0.8)")
        f.setGeometry(geom)
        self.linesLayer.startEditing()
        self.linesLayer.addFeatures([f])
        self.linesLayer.commitChanges()
        # check the second snapped point is OK
        m = u.snapToMap(QPoint(75, 100 - 80))
        self.assertTrue(m.isValid())
        self.assertTrue(m.hasVertex())
        self.assertEqual(m.point(), QgsPointXY(0.7, 0.8))
        self.pointsLayer.setDependencies([])
        self.pointsLayer2.setDependencies([])
Example #56
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        field_name = self.parameterAsString(parameters, self.FIELD, context)
        type = self.parameterAsEnum(parameters, self.TYPE, context)
        use_field = bool(field_name)

        field_index = -1

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 20))

        if use_field:
            # keep original field type, name and parameters
            field_index = source.fields().lookupField(field_name)
            if field_index >= 0:
                fields.append(source.fields()[field_index])
        if type == 0:
            # envelope
            fields.append(QgsField('width', QVariant.Double, '', 20, 6))
            fields.append(QgsField('height', QVariant.Double, '', 20, 6))
            fields.append(QgsField('area', QVariant.Double, '', 20, 6))
            fields.append(QgsField('perimeter', QVariant.Double, '', 20, 6))
        elif type == 1:
            # oriented rect
            fields.append(QgsField('width', QVariant.Double, '', 20, 6))
            fields.append(QgsField('height', QVariant.Double, '', 20, 6))
            fields.append(QgsField('angle', QVariant.Double, '', 20, 6))
            fields.append(QgsField('area', QVariant.Double, '', 20, 6))
            fields.append(QgsField('perimeter', QVariant.Double, '', 20, 6))
        elif type == 2:
            # circle
            fields.append(QgsField('radius', QVariant.Double, '', 20, 6))
            fields.append(QgsField('area', QVariant.Double, '', 20, 6))
        elif type == 3:
            # convex hull
            fields.append(QgsField('area', QVariant.Double, '', 20, 6))
            fields.append(QgsField('perimeter', QVariant.Double, '', 20, 6))

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields,
                                               QgsWkbTypes.Polygon,
                                               source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        if field_index >= 0:
            geometry_dict = {}
            bounds_dict = {}
            total = 50.0 / source.featureCount() if source.featureCount(
            ) else 1
            features = source.getFeatures(
                QgsFeatureRequest().setSubsetOfAttributes([field_index]))
            for current, f in enumerate(features):
                if feedback.isCanceled():
                    break

                if not f.hasGeometry():
                    continue

                if type == 0:
                    # bounding boxes - calculate on the fly for efficiency
                    if not f[field_index] in bounds_dict:
                        bounds_dict[
                            f[field_index]] = f.geometry().boundingBox()
                    else:
                        bounds_dict[f[field_index]].combineExtentWith(
                            f.geometry().boundingBox())
                else:
                    if not f[field_index] in geometry_dict:
                        geometry_dict[f[field_index]] = [f.geometry()]
                    else:
                        geometry_dict[f[field_index]].append(f.geometry())

                feedback.setProgress(int(current * total))

            if type == 0:
                # bounding boxes
                current = 0
                total = 50.0 / len(bounds_dict) if bounds_dict else 1
                for group, rect in bounds_dict.items():
                    if feedback.isCanceled():
                        break

                    # envelope
                    feature = QgsFeature()
                    feature.setGeometry(QgsGeometry.fromRect(rect))
                    feature.setAttributes([
                        current, group,
                        rect.width(),
                        rect.height(),
                        rect.area(),
                        rect.perimeter()
                    ])
                    sink.addFeature(feature, QgsFeatureSink.FastInsert)
                    geometry_dict[group] = None

                    feedback.setProgress(50 + int(current * total))
                    current += 1
            else:
                current = 0
                total = 50.0 / len(geometry_dict) if geometry_dict else 1

                for group, geometries in geometry_dict.items():
                    if feedback.isCanceled():
                        break

                    feature = self.createFeature(feedback, current, type,
                                                 geometries, group)
                    sink.addFeature(feature, QgsFeatureSink.FastInsert)
                    geometry_dict[group] = None

                    feedback.setProgress(50 + int(current * total))
                    current += 1
        else:
            total = 80.0 / source.featureCount() if source.featureCount(
            ) else 1
            features = source.getFeatures(
                QgsFeatureRequest().setSubsetOfAttributes([]))
            geometry_queue = []
            bounds = QgsRectangle()
            for current, f in enumerate(features):
                if feedback.isCanceled():
                    break

                if not f.hasGeometry():
                    continue

                if type == 0:
                    # bounding boxes, calculate on the fly for efficiency
                    bounds.combineExtentWith(f.geometry().boundingBox())
                else:
                    geometry_queue.append(f.geometry())
                feedback.setProgress(int(current * total))

            if not feedback.isCanceled():
                if type == 0:
                    feature = QgsFeature()
                    feature.setGeometry(QgsGeometry.fromRect(bounds))
                    feature.setAttributes([
                        0,
                        bounds.width(),
                        bounds.height(),
                        bounds.area(),
                        bounds.perimeter()
                    ])
                else:
                    feature = self.createFeature(feedback, 0, type,
                                                 geometry_queue)
                sink.addFeature(feature, QgsFeatureSink.FastInsert)

        return {self.OUTPUT: dest_id}
 def center_to_point(self, point):
     canvas = self.iface.mapCanvas()
     new_extent = QgsRectangle(canvas.extent())
     new_extent.scale(1, point)
     canvas.setExtent(new_extent)
     canvas.refresh()
Example #58
0
 def testQgsRectangleRepr(self):
     r = QgsRectangle(1, 2, 3, 4)
     self.assertEqual(r.__repr__(), '<QgsRectangle: 1 2, 3 4>')
    def testRectangle(self):
        rect = QgsReferencedRectangle(QgsRectangle(0.0, 1.0, 20.0, 10.0), QgsCoordinateReferenceSystem('epsg:3111'))
        self.assertEqual(rect.xMinimum(), 0.0)
        self.assertEqual(rect.yMinimum(), 1.0)
        self.assertEqual(rect.xMaximum(), 20.0)
        self.assertEqual(rect.yMaximum(), 10.0)
        self.assertEqual(rect.crs().authid(), 'EPSG:3111')

        rect.setCrs(QgsCoordinateReferenceSystem('epsg:28356'))
        self.assertEqual(rect.crs().authid(), 'EPSG:28356')

        # in variant
        v = QVariant(QgsReferencedRectangle(QgsRectangle(1.0, 2.0, 3.0, 4.0), QgsCoordinateReferenceSystem('epsg:3111')))
        self.assertEqual(v.value().xMinimum(), 1.0)
        self.assertEqual(v.value().yMinimum(), 2.0)
        self.assertEqual(v.value().xMaximum(), 3.0)
        self.assertEqual(v.value().yMaximum(), 4.0)
        self.assertEqual(v.value().crs().authid(), 'EPSG:3111')

        # to rectangle
        r = QgsRectangle(rect)
        self.assertEqual(r.xMinimum(), 0.0)
        self.assertEqual(r.yMinimum(), 1.0)
        self.assertEqual(r.xMaximum(), 20.0)
        self.assertEqual(r.yMaximum(), 10.0)

        # test that QgsReferencedRectangle IS a QgsRectangle
        r2 = QgsRectangle(5, 6, 30, 40)
        r2.combineExtentWith(rect)
        self.assertEqual(r2.xMinimum(), 0.0)
        self.assertEqual(r2.yMinimum(), 1.0)
        self.assertEqual(r2.xMaximum(), 30.0)
        self.assertEqual(r2.yMaximum(), 40.0)
Example #60
0
    def testContains(self):
        rect1 = QgsRectangle(0.0, 0.0, 5.0, 5.0)
        rect2 = QgsRectangle(2.0, 2.0, 7.0, 7.0)
        pnt1 = QgsPointXY(4.0, 4.0)
        pnt2 = QgsPointXY(6.0, 2.0)

        rect3 = rect1.intersect(rect2)

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(rect3)))
        assert rect1.contains(rect3), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect2.contains(rect3)))
        assert rect2.contains(rect3), myMessage

        # test for point
        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect1.contains(pnt1)))
        assert rect1.contains(pnt1), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect2.contains(pnt1)))
        assert rect2.contains(pnt1), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect3.contains(pnt1)))
        assert rect3.contains(pnt1), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (False, rect1.contains(pnt2)))
        self.assertFalse(rect1.contains(pnt2), myMessage)

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect2.contains(pnt2)))
        assert rect2.contains(pnt2), myMessage

        myMessage = ('Expected: %s\nGot: %s\n' % (False, rect3.contains(pnt2)))
        self.assertFalse(rect3.contains(pnt2), myMessage)

        myMessage = ('Expected: %s\nGot: %s\n' % (True, rect3.contains(pnt1)))
        self.assertTrue(rect3.contains(pnt1), myMessage)