Beispiel #1
0
 def polygons_to_geometry(self, polygons):
     """Returns a QgsGeometry object from a list of polygons"""
     geoms = QgsMultiPolygon()
     for polygon in polygons:
         g = self.read_polygon(polygon)
         geoms.addGeometry(g)
     return QgsGeometry(geoms)
Beispiel #2
0
    def convertToPolygons(self, geometry):
        surfaces = self.getSurfaces(geometry.constGet())
        output_wkb = self.convertWkbToPolygons(geometry.wkbType())
        out_geom = None
        if QgsWkbTypes.flatType(output_wkb) == QgsWkbTypes.MultiPolygon:
            out_geom = QgsMultiPolygon()
        else:
            out_geom = QgsMultiSurface()

        for surface in surfaces:
            out_geom.addGeometry(surface)

        return out_geom
Beispiel #3
0
    def convertToPolygons(self, geometry):
        surfaces = self.getSurfaces(geometry.constGet())
        output_wkb = self.convertWkbToPolygons(geometry.wkbType())
        out_geom = None
        if QgsWkbTypes.flatType(output_wkb) == QgsWkbTypes.MultiPolygon:
            out_geom = QgsMultiPolygon()
        else:
            out_geom = QgsMultiSurface()

        for surface in surfaces:
            out_geom.addGeometry(surface)

        return out_geom
Beispiel #4
0
def tzf_to_qgis_polygon(tzdata):
    if not tzdata or len(tzdata) < 1:
        return None
    multi_poly = QgsMultiPolygon()
    for tzpoly in tzdata:
        holes = []
        poly = QgsPolygon()
        for x, part in enumerate(tzpoly):
            if x == 0:
                outer_ls = QgsLineString(part[0], part[1])
                poly.setExteriorRing(outer_ls)
            else:
                hole_ls = QgsLineString(part[0], part[1])
                holes.append(hole_ls)
        poly.setInteriorRings(holes)
        multi_poly.addGeometry(poly)
    return (QgsGeometry(multi_poly))
Beispiel #5
0
    def process(self, name, desc, alt_mode, begin, end, when):
        if self.extDataSize > 0:
            extAttr = [''] * self.extDataSize
        for key in self.extendedData.keys():
            if key in self.extDataMap:
                extAttr[self.extDataMap[key]] = self.extendedData[key]
        # POINTS
        if len(self.ptPts) != 0:
            for x, pt in enumerate(self.ptPts):
                feature = QgsFeature()
                feature.setGeometry(QgsGeometry(pt))
                attr = [
                    name,
                    self.folderString(), desc, self.ptAltitude[x], alt_mode,
                    begin, end, when
                ]
                if self.extDataSize > 0:
                    attr.extend(extAttr)
                feature.setAttributes(attr)
                self.addpoint.emit(feature)

        # LINES - lineStrings is a list of QgsLineString
        if len(self.lineStrings) != 0:
            feature = QgsFeature()
            if len(self.lineStrings) == 1:
                feature.setGeometry(QgsGeometry(self.lineStrings[0]))
            else:
                g = QgsMultiLineString()
                for lineStr in self.lineStrings:
                    g.addGeometry(lineStr)
                feature.setGeometry(QgsGeometry(g))
            attr = [
                name,
                self.folderString(), desc, 0, alt_mode, begin, end, when
            ]
            if self.extDataSize > 0:
                attr.extend(extAttr)
            feature.setAttributes(attr)
            self.addline.emit(feature)

        # POLYGONS
        if len(self.polygons) != 0:
            feature = QgsFeature()
            if len(self.polygons) == 1:
                feature.setGeometry(QgsGeometry(self.polygons[0]))
            else:
                g = QgsMultiPolygon()
                for poly in self.polygons:
                    g.addGeometry(poly)
                feature.setGeometry(QgsGeometry(g))
            attr = [
                name,
                self.folderString(), desc, 0, alt_mode, begin, end, when
            ]
            if self.extDataSize > 0:
                attr.extend(extAttr)
            feature.setAttributes(attr)
            self.addpolygon.emit(feature)
Beispiel #6
0
    def splitPolygon(self, geom):
        z_func = lambda x, y: self.valueOnSurface(x, y) or 0
        cache = FunctionCacheXY(z_func)
        z_func = cache.func

        polygons = QgsMultiPolygon()
        for poly in self._splitPolygon(geom):
            p = QgsPolygon()
            ring = QgsLineString()
            for pt in poly[0]:
                ring.addVertex(QgsPoint(pt.x(), pt.y(), z_func(pt.x(), pt.y())))
            p.setExteriorRing(ring)

            for bnd in poly[1:]:
                ring = QgsLineString()
                for pt in bnd:
                    ring.addVertex(QgsPoint(pt.x(), pt.y(), z_func(pt.x(), pt.y())))
                p.addInteriorRing(ring)
            polygons.addGeometry(p)
        return QgsGeometry(polygons)
Beispiel #7
0
    def get_constraint_geometry(self):
        """Returns the geometry from the constraint layer and rule

        :return: the constraint geometry and the number of matched records
        :rtype: tuple( MultiPolygon, integer)
        """

        constraint_layer = get_qgis_layer(self.constraint.constraint_layer)
        layer = get_qgis_layer(self.constraint.layer)

        # Get the geometries from constraint layer and rule
        qgis_feature_request = QgsFeatureRequest()
        qgis_feature_request.setFilterExpression(self.rule)

        features = get_qgis_features(constraint_layer,
                                     qgis_feature_request,
                                     exclude_fields='__all__')

        if not features:
            return '', 0

        geometry = QgsMultiPolygon()

        for feature in features:
            geom = feature.geometry()
            if geom.isMultipart():
                geom = [g for g in geom.constGet()]
            else:
                geom = [geom.constGet()]

            i = 0
            for g in geom:
                geometry.insertGeometry(g.clone(), 0)
                i += 1

        # Now, transform into a GEOS geometry
        if constraint_layer.crs() != layer.crs():
            ct = QgsCoordinateTransform(
                QgsCoordinateReferenceSystem(constraint_layer.crs()),
                QgsCoordinateReferenceSystem(layer.crs()),
                QgsCoordinateTransformContext())
            geometry.transform(ct)

        constraint_geometry = MultiPolygon.from_ewkt(
            'SRID=%s;' % layer.crs().postgisSrid() + geometry.asWkt())

        return constraint_geometry, constraint_geometry.num_geom
    def getRings(self, geometry):
        rings = []

        # TODO: remove when the error is resolved
        # Error: The expected object type is a QgsCurvePolygon but it receives a QgsPoint, however the WKT of the
        #        QgsPoint corresponds to either a QgsPolygon or QgsMultiPolygon (yeap, it must be a bug in QGIS)
        if type(geometry) == QgsPoint or type(geometry) == QgsLineString:
            geom = QgsGeometry().fromWkt(geometry.asWkt())
            curve = None
            if geom.isMultipart():
                curve = QgsMultiPolygon()
                curve.fromWkt(geom.asWkt())
            else:
                curve = QgsPolygon()
                curve.fromWkt(geom.asWkt())

            geometry = curve.toCurveType()

        if isinstance(geometry, QgsGeometryCollection):
            # collection
            for i in range(geometry.numGeometries()):
                if QgsWkbTypes.geometryType(geometry.geometryN(
                        i).wkbType()) == QgsWkbTypes.PolygonGeometry:
                    rings.extend(self.getRings(geometry.geometryN(i)))
        else:
            # Converts geometry to curve, because exteriorRing is a method from curve polygons
            if isinstance(geometry, QgsPolygon):
                geom = geometry.toCurveType()
                geometry = geom

            # not collection
            rings.append(geometry.exteriorRing().clone())
            for i in range(geometry.numInteriorRings()):
                rings.append(geometry.interiorRing(i).clone())

        return rings
Beispiel #9
0
    def txestGeometryRendering(self):
        '''Tests rendering a bunch of different geometries, including bad/odd geometries.'''

        empty_multipolygon = QgsMultiPolygon()
        empty_multipolygon.addGeometry(QgsPolygon())
        empty_polygon = QgsPolygon()
        empty_linestring = QgsLineString()

        tests = [
            {
                'name': 'Point',
                'wkt': 'Point (1 2)',
                'reference_image': 'point'
            },
            {
                'name': 'MultiPoint',
                'wkt': 'MultiPoint ((10 30),(40 20),(30 10),(20 10))',
                'reference_image': 'multipoint'
            },
            {
                'name': 'LineString',
                'wkt': 'LineString (0 0,3 4,4 3)',
                'reference_image': 'linestring'
            },
            {
                'name': 'Empty LineString',
                'geom': QgsGeometry(empty_linestring),
                'reference_image': 'empty'
            },
            {
                'name': 'MultiLineString',
                'wkt':
                'MultiLineString ((0 0, 1 0, 1 1, 2 1, 2 0), (3 1, 5 1, 5 0, 6 0))',
                'reference_image': 'multilinestring'
            },
            {
                'name': 'Polygon',
                'wkt':
                'Polygon ((0 0, 10 0, 10 10, 0 10, 0 0),(5 5, 7 5, 7 7 , 5 7, 5 5))',
                'reference_image': 'polygon'
            },
            {
                'name': 'Empty Polygon',
                'geom': QgsGeometry(empty_polygon),
                'reference_image': 'empty'
            },
            {
                'name': 'MultiPolygon',
                'wkt':
                'MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),((4 0, 5 0, 5 2, 3 2, 3 1, 4 1, 4 0)))',
                'reference_image': 'multipolygon'
            },
            {
                'name': 'Empty MultiPolygon',
                'geom': QgsGeometry(empty_multipolygon),
                'reference_image': 'empty'
            },
            {
                'name': 'CircularString',
                'wkt': 'CIRCULARSTRING(268 415,227 505,227 406)',
                'reference_image': 'circular_string'
            },
            {
                'name': 'CompoundCurve',
                'wkt':
                'COMPOUNDCURVE((5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), (9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))',
                'reference_image': 'compound_curve'
            },
            {
                'name': 'CurvePolygon',
                'wkt': 'CURVEPOLYGON(CIRCULARSTRING(1 3, 3 5, 4 7, 7 3, 1 3))',
                'reference_image': 'curve_polygon'
            },
            {
                'name': 'MultiCurve',
                'wkt':
                'MultiCurve((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0, 2 1,2 2))',
                'reference_image': 'multicurve'
            },
            {
                'name': 'CurvePolygon_no_arc',  # refs #14028
                'wkt': 'CURVEPOLYGON(LINESTRING(1 3, 3 5, 4 7, 7 3, 1 3))',
                'reference_image': 'curve_polygon_no_arc'
            }
        ]

        for test in tests:

            def get_geom():
                if 'geom' not in test:
                    geom = QgsGeometry.fromWkt(test['wkt'])
                    assert geom and not geom.isNull(
                    ), 'Could not create geometry {}'.format(test['wkt'])
                else:
                    geom = test['geom']
                return geom

            geom = get_geom()
            rendered_image = self.renderGeometry(geom)
            assert self.imageCheck(test['name'], test['reference_image'],
                                   rendered_image)

            # Note - each test is repeated with the same geometry and reference image, but with added
            # z and m dimensions. This tests that presence of the dimensions does not affect rendering

            # test with Z
            geom_z = get_geom()
            geom_z.get().addZValue(5)
            rendered_image = self.renderGeometry(geom_z)
            assert self.imageCheck(test['name'] + 'Z', test['reference_image'],
                                   rendered_image)

            # test with ZM
            geom_z.get().addMValue(15)
            rendered_image = self.renderGeometry(geom_z)
            assert self.imageCheck(test['name'] + 'ZM',
                                   test['reference_image'], rendered_image)

            # test with M
            geom_m = get_geom()
            geom_m.get().addMValue(15)
            rendered_image = self.renderGeometry(geom_m)
            assert self.imageCheck(test['name'] + 'M', test['reference_image'],
                                   rendered_image)
Beispiel #10
0
    def get_inner_rings_layer(self,
                              plot_layer,
                              id_field=ID_FIELD,
                              use_selection=False):
        id_field_idx = plot_layer.fields().indexFromName(id_field)
        request = QgsFeatureRequest().setSubsetOfAttributes([id_field_idx])
        polygons = plot_layer.getSelectedFeatures(
            request) if use_selection else plot_layer.getFeatures(request)

        layer = QgsVectorLayer("LineString?crs=EPSG:{}".format(DEFAULT_EPSG),
                               "rings", "memory")
        data_provider = layer.dataProvider()
        data_provider.addAttributes([QgsField(ID_FIELD, QVariant.Int)])
        layer.updateFields()

        features = []

        for polygon in polygons:
            polygon_geom = polygon.geometry()
            is_multipart = polygon_geom.isMultipart()

            # Does the current multipolygon have inner rings?
            has_inner_rings = False
            multi_polygon = None
            single_polygon = None

            if is_multipart:

                multi_polygon = polygon_geom.constGet()

                # TODO: remove when the error is resolved
                if type(multi_polygon) != QgsMultiPolygon:
                    geom = QgsMultiPolygon()
                    geom.fromWkt(polygon_geom.asWkt())
                    multi_polygon = geom

                for part in range(multi_polygon.numGeometries()):
                    if multi_polygon.ringCount(part) > 1:
                        has_inner_rings = True
                        break
            else:
                single_polygon = polygon_geom.constGet()

                # TODO: remove when the error is resolved
                if type(single_polygon) != QgsPolygon:
                    geom = QgsPolygon()
                    geom.fromWkt(polygon_geom.asWkt())
                    single_polygon = geom

                if single_polygon.numInteriorRings() > 0:
                    has_inner_rings = True

            if has_inner_rings:

                if is_multipart and multi_polygon:
                    for i in range(multi_polygon.numGeometries()):
                        temp_polygon = multi_polygon.geometryN(i)

                        # TODO: remove when the error is resolved
                        if type(temp_polygon) != QgsPolygon:
                            geom = QgsPolygon()
                            geom.fromWkt(temp_polygon.asWkt())
                            temp_polygon = geom

                        for j in range(temp_polygon.numInteriorRings()):
                            new_feature = QgsVectorLayerUtils().createFeature(
                                layer,
                                QgsGeometry(
                                    temp_polygon.interiorRing(j).clone()),
                                {0: polygon[id_field]})
                            features.append(new_feature)

                elif not is_multipart and single_polygon:
                    for j in range(single_polygon.numInteriorRings()):
                        new_feature = QgsVectorLayerUtils().createFeature(
                            layer,
                            QgsGeometry(
                                single_polygon.interiorRing(j).clone()),
                            {0: polygon[id_field]})
                        features.append(new_feature)

        layer.dataProvider().addFeatures(features)
        layer.updateExtents()
        layer.reload()
        return layer
Beispiel #11
0
    def txestGeometryRendering(self):
        '''Tests rendering a bunch of different geometries, including bad/odd geometries.'''

        empty_multipolygon = QgsMultiPolygon()
        empty_multipolygon.addGeometry(QgsPolygon())
        empty_polygon = QgsPolygon()
        empty_linestring = QgsLineString()

        tests = [{'name': 'Point',
                  'wkt': 'Point (1 2)',
                  'reference_image': 'point'},
                 {'name': 'MultiPoint',
                  'wkt': 'MultiPoint ((10 30),(40 20),(30 10),(20 10))',
                  'reference_image': 'multipoint'},
                 {'name': 'LineString',
                  'wkt': 'LineString (0 0,3 4,4 3)',
                  'reference_image': 'linestring'},
                 {'name': 'Empty LineString',
                  'geom': QgsGeometry(empty_linestring),
                  'reference_image': 'empty'},
                 {'name': 'MultiLineString',
                  'wkt': 'MultiLineString ((0 0, 1 0, 1 1, 2 1, 2 0), (3 1, 5 1, 5 0, 6 0))',
                  'reference_image': 'multilinestring'},
                 {'name': 'Polygon',
                  'wkt': 'Polygon ((0 0, 10 0, 10 10, 0 10, 0 0),(5 5, 7 5, 7 7 , 5 7, 5 5))',
                  'reference_image': 'polygon'},
                 {'name': 'Empty Polygon',
                  'geom': QgsGeometry(empty_polygon),
                  'reference_image': 'empty'},
                 {'name': 'MultiPolygon',
                  'wkt': 'MultiPolygon (((0 0, 1 0, 1 1, 2 1, 2 2, 0 2, 0 0)),((4 0, 5 0, 5 2, 3 2, 3 1, 4 1, 4 0)))',
                  'reference_image': 'multipolygon'},
                 {'name': 'Empty MultiPolygon',
                  'geom': QgsGeometry(empty_multipolygon),
                  'reference_image': 'empty'},
                 {'name': 'CircularString',
                  'wkt': 'CIRCULARSTRING(268 415,227 505,227 406)',
                  'reference_image': 'circular_string'},
                 {'name': 'CompoundCurve',
                  'wkt': 'COMPOUNDCURVE((5 3, 5 13), CIRCULARSTRING(5 13, 7 15, 9 13), (9 13, 9 3), CIRCULARSTRING(9 3, 7 1, 5 3))',
                  'reference_image': 'compound_curve'},
                 {'name': 'CurvePolygon',
                  'wkt': 'CURVEPOLYGON(CIRCULARSTRING(1 3, 3 5, 4 7, 7 3, 1 3))',
                  'reference_image': 'curve_polygon'},
                 {'name': 'MultiCurve',
                  'wkt': 'MultiCurve((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0, 2 1,2 2))',
                  'reference_image': 'multicurve'},
                 {'name': 'CurvePolygon_no_arc',  # refs #14028
                  'wkt': 'CURVEPOLYGON(LINESTRING(1 3, 3 5, 4 7, 7 3, 1 3))',
                  'reference_image': 'curve_polygon_no_arc'}]

        for test in tests:

            def get_geom():
                if 'geom' not in test:
                    geom = QgsGeometry.fromWkt(test['wkt'])
                    assert geom and not geom.isNull(), 'Could not create geometry {}'.format(test['wkt'])
                else:
                    geom = test['geom']
                return geom

            geom = get_geom()
            rendered_image = self.renderGeometry(geom)
            assert self.imageCheck(test['name'], test['reference_image'], rendered_image)

            # Note - each test is repeated with the same geometry and reference image, but with added
            # z and m dimensions. This tests that presence of the dimensions does not affect rendering

            # test with Z
            geom_z = get_geom()
            geom_z.get().addZValue(5)
            rendered_image = self.renderGeometry(geom_z)
            assert self.imageCheck(test['name'] + 'Z', test['reference_image'], rendered_image)

            # test with ZM
            geom_z.get().addMValue(15)
            rendered_image = self.renderGeometry(geom_z)
            assert self.imageCheck(test['name'] + 'ZM', test['reference_image'], rendered_image)

            # test with M
            geom_m = get_geom()
            geom_m.get().addMValue(15)
            rendered_image = self.renderGeometry(geom_m)
            assert self.imageCheck(test['name'] + 'M', test['reference_image'], rendered_image)
    def createGeom(self, coords):

        crsDest = self.__layer.crs()

        rc = ReprojectCoordinates(self.crsId, crsDest.srsid(), self.__hasZ, self.__hasM)
        if self.crsId != crsDest.srsid():
            coordsPoint = list(rc.reproject(coords, True))
        else:
            coordsPoint = list(rc.copyCoordstoPoints(coords))

        # Point and multipoint Geometry
        # Always 1 part, 0 element of matrix
        if self.__layergeometryType == QgsWkbTypes.PointGeometry:
            if self.__isMultiType:
                multipoint = QgsMultiPoint()
                for coords_item in coordsPoint[0][1]:
                    multipoint.addGeometry(coords_item)

                geom = QgsGeometry(multipoint)
                self.createFeature(geom)
            else:
                geom = QgsGeometry(coordsPoint[0][1][0])
                self.createFeature(geom)

        elif self.__layergeometryType == QgsWkbTypes.LineGeometry:
            if self.__isMultiType:
                multiline = QgsGeometry(QgsMultiLineString())
                for j in range(len(coordsPoint)):
                    line = QgsLineString(coordsPoint[j][1])
                    multiline.addPart(line)
                self.createFeature(multiline)
            else:
                line = QgsGeometry(QgsLineString(coordsPoint[0][1]))
                self.createFeature(line)

        elif self.__layergeometryType == QgsWkbTypes.PolygonGeometry:
            if self.__isMultiType:
                multipoly = QgsGeometry(QgsMultiPolygon())

                for i in range(len(coordsPoint)):
                    if int(coordsPoint[i][0]) > 0:
                        mycurve = QgsLineString(coordsPoint[i][1])
                        poly = QgsPolygon()
                        poly.setExteriorRing(mycurve)

                        polyGeometry = QgsGeometry(QgsPolygon(poly))
                        for j in range(len(coordsPoint)):
                            if int(coordsPoint[j][0]) < 0:
                                containsAllPoints = True
                                for k in range(len(coordsPoint[j][1])):
                                    containsAllPoints = True
                                    curPoint = coordsPoint[j][1][k].clone()
                                    containsAllPoints = containsAllPoints \
                                                    and polyGeometry.contains(QgsPointXY(curPoint.x(), curPoint.y()))
                                if containsAllPoints:
                                    mycurve = QgsLineString(coordsPoint[j][1])
                                    poly.addInteriorRing(mycurve)

                        multipoly.addPart(poly)
                self.createFeature(multipoly)
            else:
                extRing = 0
                for i in range(len(coordsPoint)):
                    if int(coordsPoint[i][0]) > 0:
                       extRing = i

                mycurve = QgsLineString(coordsPoint[extRing][1])
                poly = QgsPolygon()
                poly.setExteriorRing(mycurve)

                polyGeometry = QgsGeometry(QgsPolygon(poly))

                for i in range(len(coordsPoint)):
                    if int(coordsPoint[i][0]) < 0:
                        containsAllPoints = True
                        for j in range(len(coordsPoint[i][1])):
                            containsAllPoints = True
                            curPoint = coordsPoint[i][1][j].clone()
                            containsAllPoints = containsAllPoints \
                                                and polyGeometry.contains(QgsPointXY(curPoint.x(), curPoint.y()))
                        if containsAllPoints:
                            mycurve = QgsLineString(coordsPoint[i][1])
                            poly.addInteriorRing(mycurve)
                        else:
                            QMessageBox.question(self.iface.mainWindow(),
                                                 self.translate_str("Ring not in exterior contour"),
                                                 self.translate_str("The new geometry of the feature"
                                                                    " isn't valid. Do you want to use it anyway?"),
                                                 QMessageBox.Yes, QMessageBox.No)

                self.createFeature(QgsGeometry(poly))