Ejemplo n.º 1
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.POLYGONS, context)
        parts = self.parameterAsInt(parameters, self.PARTS, context)

        fields = source.fields()
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               source.fields(), source.wkbType(), source.sourceCrs())

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, feat in enumerate(features):
            if feedback.isCanceled():
                break

            geom = feat.geometry()
            if geom.isMultipart():
                out_feature = feat
                geoms = geom.asGeometryCollection()
                geom_area = [(i, geoms[i].area()) for i in range(len(geoms))]
                geom_area.sort(key=itemgetter(1))
                if parts == 1:
                    out_feature.setGeometry(geoms[geom_area[-1][0]])
                elif parts > len(geoms):
                    out_feature.setGeometry(geom)
                else:
                    out_feature.setGeometry(geom)
                    geomres = [geoms[i].asPolygon() for i, a in geom_area[-1 * parts:]]
                    out_feature.setGeometry(QgsGeometry.fromMultiPolygonXY(geomres))
                sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
            else:
                sink.addFeature(feat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 2
0
    def addResultToLayer(self, layer, result, lyrDefault, mode):
        if len(result) > 0:
            layer.startEditing()
            feats = []

            if lyrDefault is True:
                bbox = QgsRectangle()
                bbox.setMinimal()

            for res in result:
                feat = QgsFeature()
                if mode == 'web':
                    feat.setGeometry(
                        QgsGeometry.fromMultiPolygonXY(res["geom"]))
                else:
                    feat.setGeometry(QgsGeometry.fromWkt(res["wkt"]))

                feat.setAttributes([
                    res["id"], res["partido"], res["partida"],
                    res["nomenclatura"], res["codigo"], res["layer"]
                ])
                feats.append(feat)
                if lyrDefault is True:
                    bbox.combineExtentWith(feat.geometry().boundingBox())

            layer.dataProvider().addFeatures(feats)
            layer.commitChanges()
            layer.updateExtents()

            if lyrDefault is True:
                self.canvas.setExtent(self.setBboxMap(bbox, layer))
            else:
                self.canvas.setExtent(self.setBboxMap(layer.extent(), layer))
Ejemplo n.º 3
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.POLYGONS, context)
        parts = self.parameterAsInt(parameters, self.PARTS, context)

        fields = source.fields()
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               source.fields(), source.wkbType(), source.sourceCrs())

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, feat in enumerate(features):
            if feedback.isCanceled():
                break

            geom = feat.geometry()
            if geom.isMultipart():
                out_feature = feat
                geoms = geom.asGeometryCollection()
                geom_area = [(i, geoms[i].area()) for i in range(len(geoms))]
                geom_area.sort(key=itemgetter(1))
                if parts == 1:
                    out_feature.setGeometry(geoms[geom_area[-1][0]])
                elif parts > len(geoms):
                    out_feature.setGeometry(geom)
                else:
                    out_feature.setGeometry(geom)
                    geomres = [geoms[i].asPolygon() for i, a in geom_area[-1 * parts:]]
                    out_feature.setGeometry(QgsGeometry.fromMultiPolygonXY(geomres))
                sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
            else:
                sink.addFeature(feat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Ejemplo n.º 4
0
 def creator_geometry_changed(self, qgsfId, geom):
     """
        Called when feature is changed
        @param qgsfId:      Id of added feature
        @type  qgsfId:      qgis.core.QgsFeature.QgsFeatureId
        @param geom:        geometry of added feature
        @type  geom:        qgis.core.QgsGeometry
     """
     if qgsfId in self.added_building_ids:
         if geom.wkbType() == QgsWkbTypes.Polygon:
             geom = QgsGeometry.fromMultiPolygonXY([geom.asPolygon()])
         wkt = geom.asWkt()
         if not wkt:
             self.disable_UI_functions()
             self.geom = None
             return
         sql = general_select.convert_geometry
         result = self.db.execute_return(sql, (wkt, ))
         self.geom = result.fetchall()[0][0]
     else:
         self.error_dialog = ErrorDialog()
         self.error_dialog.fill_report(
             "\n -------------------- WRONG GEOMETRY EDITED ------"
             "-------------- \n\nOnly current added outline can "
             "be edited. Please go to [Edit Geometry] to edit "
             "existing outlines.")
         self.error_dialog.show()
Ejemplo n.º 5
0
    def saveParcel(self):
        if not self.layernameValid(): return
        municipality = self.ui.municipalityCbx.currentText()
        department = self.ui.departmentCbx.currentText()

        niscodes = [
            n['municipalityCode'] for n in self.municipalities
            if n['municipalityName'] == municipality
        ]
        niscode = (niscodes[0] if len(niscodes) else '')
        departmentcodes = [
            n['departmentCode'] for n in self.departments
            if n['departmentName'] == department
        ]
        departmentcode = (departmentcodes[0] if len(departmentcodes) else '')

        section = self.ui.sectionCbx.currentText()
        parcelNr = self.ui.parcelCbx.currentText()

        if '' in (niscode, departmentcode, section, parcelNr): return

        parcelInfo = self.parcel.getParcel(niscode, departmentcode, section,
                                           parcelNr, 31370, 'full')

        geojson = self.perc.getPercGeom(parcelInfo['capakey'])
        if len(geojson['features']) > 0:
            shape = geojson['features'][0]['geometry']
        else:
            shape = json.loads(parcelInfo['geometry']['shape'])

        pts = [n.asPolygon() for n in self.PolygonsFromJson(shape)]
        mPolygon = QgsGeometry.fromMultiPolygonXY(pts)
        self.ph.save_parcel_polygon(
            mPolygon, parcelInfo, self.layerName, self.saveToFile, self,
            os.path.join(self.startDir, self.layerName))
Ejemplo n.º 6
0
def qgsgeom_from_mpl_collec(collections):
    polygons = []
    for i, polygon in enumerate(collections):
        mpoly = []
        for path in polygon.get_paths():
            path.should_simplify = False
            poly = path.to_polygons()
            if len(poly) > 0 and len(poly[0]) > 3:
                exterior = [QgsPointXY(*p.tolist()) for p in poly[0]]
                holes = [[QgsPointXY(*p.tolist()) for p in h] for h in poly[1:]
                         if len(h) > 3]
                if len(holes) == 1:
                    mpoly.append([exterior, holes[0]])
                elif len(holes) > 1:
                    mpoly.append([exterior] + [h for h in holes])
                else:
                    mpoly.append([exterior])

        if len(mpoly) == 1:
            polygons.append(QgsGeometry.fromPolygonXY(mpoly[0]))
        elif len(mpoly) > 1:
            polygons.append(QgsGeometry.fromMultiPolygonXY(mpoly))
        else:
            polygons.append(QgsGeometry.fromPolygonXY([]))
    return polygons
Ejemplo n.º 7
0
    def splitPolygon(self, geom):
        xmin, ymax, xres, yres = self.xmin, self.ymax, self.xres, self.yres

        polygons = []
        for x, vi in self.vSplit(geom):
            for y in self.hIntersects(vi):
                pt0 = QgsPointXY(xmin + x * xres, ymax - y * yres)
                pt1 = QgsPointXY(xmin + x * xres, ymax - (y + 1) * yres)
                pt2 = QgsPointXY(xmin + (x + 1) * xres, ymax - (y + 1) * yres)
                pt3 = QgsPointXY(xmin + (x + 1) * xres, ymax - y * yres)
                quad = QgsGeometry.fromPolygonXY([[pt0, pt1, pt2, pt3, pt0]])
                tris = [[[pt0, pt1, pt3, pt0]], [[pt3, pt1, pt2, pt3]]]

                if geom.contains(quad):
                    polygons += tris
                else:
                    for i, tri in enumerate(
                            map(QgsGeometry.fromPolygonXY, tris)):
                        if geom.contains(tri):
                            polygons.append(tris[i])
                        elif geom.intersects(tri):
                            poly = geom.intersection(tri)
                            if poly.isMultipart():
                                polygons += poly.asMultiPolygon()
                            else:
                                polygons.append(poly.asPolygon())
        return QgsGeometry.fromMultiPolygonXY(polygons)
Ejemplo n.º 8
0
def _swap_qgs_geometry(qgsgeom):
    if qgsgeom.wkbType() == QgsWkbTypes.Point:
        p = qgsgeom.asPoint()
        qgsgeom = QgsGeometry.fromPointXY(QgsPointXY(p[1], p[0]))
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPoint:
        mp = qgsgeom.asMultiPoint()
        qgsgeom = QgsGeometry.fromMultiPointXY(
            [QgsPointXY(p[1], p[0]) for p in mp])
    elif qgsgeom.wkbType() == QgsWkbTypes.LineString:
        pl = qgsgeom.asPolyline()
        qgsgeom = QgsGeometry.fromPolylineXY(
            [QgsPointXY(p[1], p[0]) for p in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiLineString:
        mls = qgsgeom.asMultiPolyline()
        qgsgeom = QgsGeometry.fromMultiPolylineXY(
            [[QgsPointXY(p[1], p[0]) for p in pl] for pl in mls])
    elif qgsgeom.wkbType() == QgsWkbTypes.Polygon:
        pl = qgsgeom.asPolygon()
        qgsgeom = QgsGeometry.fromPolygonXY(
            [[QgsPointXY(p[1], p[0]) for p in r] for r in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPolygon:
        mp = qgsgeom.asMultiPolygon()
        qgsgeom = QgsGeometry.fromMultiPolygonXY(
            [[[QgsPointXY(p[1], p[0]) for p in r] for r in pl] for pl in mp])
    return qgsgeom
Ejemplo n.º 9
0
 def reprojectPoints(self, geom, xform):
     if geom.type() == 0:  #Point
         if geom.isMultipart():
             pnts = geom.asMultiPoint()
             newPnts = []
             for pnt in pnts:
                 newPnts += [xform.transform(pnt)]
             newGeom = QgsGeometry.fromMultiPointXY(newPnts)
             return newGeom
         else:
             pnt = geom.asPoint()
             newPnt = xform.transform(pnt)
             newGeom = QgsGeometry.fromPointXY(newPnt)
             return newGeom
     elif geom.type() == 1:  #Line
         if geom.isMultipart():
             linhas = geom.asMultiPolyline()
             newLines = []
             for linha in linhas:
                 newLine = []
                 for pnt in linha:
                     newLine += [xform.transform(pnt)]
                 newLines += [newLine]
             newGeom = QgsGeometry.fromMultiPolylineXY(newLines)
             return newGeom
         else:
             linha = geom.asPolyline()
             newLine = []
             for pnt in linha:
                 newLine += [xform.transform(pnt)]
             newGeom = QgsGeometry.fromPolylineXY(newLine)
             return newGeom
     elif geom.type() == 2:  #Polygon
         if geom.isMultipart():
             poligonos = geom.asMultiPolygon()
             newPolygons = []
             for pol in poligonos:
                 newPol = []
                 for anel in pol:
                     newAnel = []
                     for pnt in anel:
                         newAnel += [xform.transform(pnt)]
                     newPol += [newAnel]
                 newPolygons += [newPol]
             newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons)
             return newGeom
         else:
             pol = geom.asPolygon()
             newPol = []
             for anel in pol:
                 newAnel = []
                 for pnt in anel:
                     newAnel += [xform.transform(pnt)]
                 newPol += [newAnel]
             newGeom = QgsGeometry.fromPolygonXY(newPol)
             return newGeom
     else:
         return None
Ejemplo n.º 10
0
 def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
     """
     Inverts the flow from a given feature. THE GIVEN FEATURE IS ALTERED. Standard behaviour is to not
     refresh canvas map.
     :param layer: layer containing the target feature for flipping.
     :param feature: feature to be flipped.
     :param geomType: if layer geometry type is not given, it'll calculate it (0,1 or 2)
     :param refreshCanvas: indicates whether the canvas should be refreshed after flipping feature.
     :returns: flipped feature as of [layer, feature, geometry_type].
     """
     if not geomType:
         geomType = layer.geometryType()
     # getting whether geometry is multipart or not
     # features not yet commited to layer always have SINGLE geometry
     isMulti = QgsWkbTypes.isMultiType(int(
         layer.wkbType())) and feature.id() > 0
     geom = feature.geometry()
     if geomType == 0:
         if isMulti:
             nodes = geom.asMultiPoint()
             # inverting the point list by parts
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             # setting flipped geometry
             flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes)
         else:
             # inverting the point list
             nodes = geom.asPoint()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPoint(nodes)
     elif geomType == 1:
         if isMulti:
             nodes = geom.asMultiPolyline()
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolylineXY(nodes)
         else:
             nodes = geom.asPolyline()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolylineXY(nodes)
     elif geomType == 2:
         if isMulti:
             nodes = geom.asMultiPolygon()
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes)
         else:
             nodes = geom.asPolygon()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolygonXY(nodes)
     # setting feature geometry to the flipped one
     # feature.setGeometry(flippedFeatureGeom)
     # layer.updateFeature(feature)
     layer.changeGeometry(feature.id(), flippedFeatureGeom)
     if refreshCanvas:
         self.iface.mapCanvas().refresh()
     return [layer, feature, geomType]
Ejemplo n.º 11
0
  def toQgsGeometry(self):
    count = len(self.polygons)
    if count > 1:
      polys = [polygonToQgsPolygon(poly) for poly in self.polygons]
      return QgsGeometry.fromMultiPolygonXY(polys)

    if count == 1:
      return QgsGeometry.fromPolygonXY(polygonToQgsPolygon(self.polygons[0]))

    return QgsGeometry()
Ejemplo n.º 12
0
            def getGeometry(geometry):
                def getPolygonPoints(coordinates):
                    polylines = []
                    for line in coordinates:
                        polyline = [QgsPointXY(p[0], p[1]) for p in line]
                        polylines.append(polyline)
                    return polylines

                if geometry['type'] == 'Polygon':
                    polygon = getPolygonPoints(geometry['coordinates'])
                    return QgsGeometry.fromMultiPolygonXY([polygon])
                elif geometry['type'] == 'MultiPolygon':
                    polygons = []
                    for polygon in geometry['coordinates']:
                        polygons.append(getPolygonPoints(polygon))
                    return QgsGeometry.fromMultiPolygonXY(polygons)

                else:
                    None
Ejemplo n.º 13
0
    def _process_feature(self, source_feature, made_progress=False):

        if QThread.currentThread().isInterruptionRequested():
            self.__commit()
            self.interrupted.emit(self.layer_found, self.layer_not_found)
            self.layer_found.stopEditing()
            return

        point = source_feature.geometry().asPoint()
        if self.parcels_geometry.contains(point):
            if made_progress:
                self.__commit()
                self.progressed.emit(self.layer_found, self.layer_not_found,
                                     True, 1, False, made_progress)
            return

        uldk_point = ULDKPoint(point.x(), point.y(), 2180)
        found_parcels_geometries = []
        saved = False

        try:
            uldk_response_row = self.uldk_search.search(uldk_point)
            additional_attributes = []
            for field in self.additional_output_fields:
                additional_attributes.append(source_feature[field.name()])
            try:
                found_feature = uldk_response_to_qgs_feature(
                    uldk_response_row, additional_attributes)
                geometry_wkt = found_feature.geometry().asWkt()
            except BadGeometryException:
                raise BadGeometryException("Niepoprawna geometria")
            if geometry_wkt not in self.geometries:
                saved = True
                self.layer_found.dataProvider().addFeature(found_feature)
                self.geometries.append(geometry_wkt)
                found_parcels_geometries.append(
                    found_feature.geometry().asPolygon())
                self.progressed.emit(self.layer_found, self.layer_not_found,
                                     True, 0, saved, made_progress)
        except Exception as e:
            geometry = source_feature.geometry()
            geometry_wkt = geometry.asWkt()
            if geometry_wkt not in self.not_found_geometries:
                not_found_feature = self.__make_not_found_feature(geometry, e)
                self.layer_not_found.dataProvider().addFeature(
                    not_found_feature)
                self.progressed.emit(self.layer_found, self.layer_not_found,
                                     False, 0, saved, made_progress)
                self.not_found_geometries.append(geometry_wkt)

        self.parcels_geometry.addPartGeometry(
            QgsGeometry.fromMultiPolygonXY(found_parcels_geometries))
        self.__commit()
        return saved
Ejemplo n.º 14
0
 def testQgsMultipolygonRepr(self):
     mp = QgsGeometry.fromMultiPolygonXY([
         [[QgsPointXY(1, 1),
           QgsPointXY(2, 2),
           QgsPointXY(1, 2),
           QgsPointXY(1, 1)]],
         [[QgsPointXY(2, 2),
           QgsPointXY(3, 3),
           QgsPointXY(3, 1),
           QgsPointXY(2, 2)]]
     ])
     self.assertEqual(mp.constGet().__repr__(), '<QgsMultiPolygon: MultiPolygon (((1 1, 2 2, 1 2, 1 1)),((2 2, 3 3, 3 1, 2 2)))>')
Ejemplo n.º 15
0
 def TestQgsMultipolygonRepr(self):
     mp = QgsGeometry.fromMultiPolygonXY([
         [[QgsPointXY(1, 1),
           QgsPointXY(2, 2),
           QgsPointXY(1, 2),
           QgsPointXY(1, 1)]],
         [[QgsPointXY(2, 2),
           QgsPointXY(3, 3),
           QgsPointXY(3, 1),
           QgsPointXY(2, 2)]]
     ])
     self.assertEqual(mp.constGet().__repr__(), '<QgsMultiPolygon: MultiPolygon (((1 1, 2 2, 1 2, 1 1)),((2 2, 3 3, 3 1, 2 2)))>')
Ejemplo n.º 16
0
    def toQgsGeometry(self, polygons=None):
        if polygons is None:
            polygons = self.polygons
        count = len(polygons)
        if count > 1:
            polys = [[[QgsPointXY(x, y) for x, y, z in bnd] for bnd in poly] for poly in polygons]
            return QgsGeometry.fromMultiPolygonXY(polys)

        if count == 1:
            poly = [[QgsPointXY(x, y) for x, y, z in bnd] for bnd in polygons[0]]
            return QgsGeometry.fromPolygonXY(poly)

        return QgsGeometry()
Ejemplo n.º 17
0
    def _feature_to_points(self, feature, geom_type, additional_attributes):
        geometry = feature.geometry()

        if QgsWkbTypes.hasZ(geom_type):
            geometry, geom_type = self.drop_z_from_geom(geometry, geom_type)

        features = []
        points_number = 0

        if self.transformation is not None:
            geometry.transform(self.transformation)

        if geom_type == QgsWkbTypes.LineString or geom_type == QgsWkbTypes.MultiLineString:
            points_number = 10
            geometry = geometry.buffer(0.001, 2)

        if self.parcels_geometry:
            if self.parcels_geometry.contains(geometry):
                return []
            else:
                if not geometry.isMultipart():
                    geometry.convertToMultiType()

                multi_polygon = QgsGeometry.fromMultiPolygonXY(
                    geometry.asMultiPolygon())
                geometry = multi_polygon.difference(
                    self.parcels_geometry.buffer(0.001, 2))
                if not geometry:
                    return []

        da = QgsDistanceArea()
        da.setSourceCrs(CRS_2180, QgsProject.instance().transformContext())
        da.setEllipsoid(QgsProject.instance().ellipsoid())

        points_number = 20 if not points_number else points_number
        area = int(da.measureArea(geometry)) / 10000
        if area > 1:
            points_number *= area
        points = geometry.randomPointsInPolygon(points_number)

        for point in points:
            feature = QgsFeature()

            if additional_attributes:
                feature.setFields(self.fields_to_add)
                feature.setAttributes(additional_attributes)

            feature.setGeometry(QgsGeometry.fromPointXY(point))
            features.append(feature)

        return features
Ejemplo n.º 18
0
    def parse_feature_response(self, response):
        if response.status_code != 200:
            if not isinstance(response.exception, RequestsExceptionUserAbort):
                self.info("Error in feature response with status code: "
                          "{} from {}".format(response.status_code,
                                              response.url))
            return

        data = json.loads(response.content.decode('utf-8'))
        self.dbg_info(data.keys())
        self.dbg_info(data['properties'])
        self.dbg_info(data['geometry'])
        self.dbg_info(data['crs'])
        self.dbg_info(data['type'])

        assert data['crs']['properties'][
            'name'] == 'urn:ogc:def:crs:EPSG::2056'

        geometry_type = data['geometry']['type']
        geometry = QgsGeometry()

        if geometry_type.lower() == 'point':
            geometry = QgsGeometry.fromPointXY(
                QgsPointXY(data['geometry']['coordinates'][0],
                           data['geometry']['coordinates'][1]))

        elif geometry_type.lower() == 'polygon':
            rings = data['geometry']['coordinates']
            for r in range(0, len(rings)):
                for p in range(0, len(rings[r])):
                    rings[r][p] = QgsPointXY(rings[r][p][0], rings[r][p][1])
            geometry = QgsGeometry.fromPolygonXY(rings)

        elif geometry_type.lower() == 'multipolygon':
            islands = data['geometry']['coordinates']
            for i in range(0, len(islands)):
                for r in range(0, len(islands[i])):
                    for p in range(0, len(islands[i][r])):
                        islands[i][r][p] = QgsPointXY(islands[i][r][p][0],
                                                      islands[i][r][p][1])
            geometry = QgsGeometry.fromMultiPolygonXY(islands)

        else:
            # SoLocator does not handle {geometry_type} yet. Please contact support
            self.info(
                'SoLocator unterstützt den Geometrietyp {geometry_type} nicht.'
                ' Bitte kontaktieren Sie den Support.'.format(
                    geometry_type=geometry_type), Qgis.Warning)

        geometry.transform(self.transform_ch)
        self.highlight(geometry)
Ejemplo n.º 19
0
    def transform(self, meta_features, force_reduction_factor, geometry):
        """Transform the geometry based on the force reduction factor."""

        if geometry.isMultipart():
            geometries = []
            for polygon in geometry.asMultiPolygon():
                new_polygon = self.transform_polygon(polygon, meta_features,
                                                     force_reduction_factor)
                geometries.append(new_polygon)
            return QgsGeometry.fromMultiPolygonXY(geometries)
        else:
            polygon = geometry.asPolygon()
            new_polygon = self.transform_polygon(polygon, meta_features,
                                                 force_reduction_factor)
            return QgsGeometry.fromPolygon(new_polygon)
Ejemplo n.º 20
0
    def testMeasureMultiPolygon(self):
        # +-+-+ +-+-+
        # |   | |   |
        # + +-+ +-+ +
        # | |     | |
        # +-+     +-+
        polygon = QgsGeometry.fromMultiPolygonXY(
            [
                [[QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 2), QgsPointXY(0, 2), QgsPointXY(0, 0), ]],
                [[QgsPointXY(4, 0), QgsPointXY(5, 0), QgsPointXY(5, 2), QgsPointXY(3, 2), QgsPointXY(3, 1), QgsPointXY(4, 1), QgsPointXY(4, 0), ]]
            ]
        )

        da = QgsDistanceArea()
        area = da.measureArea(polygon)
        assert area == 6, 'Expected:\n%f\nGot:\n%f\n' % (6, area)

        perimeter = da.measurePerimeter(polygon)
        assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
Ejemplo n.º 21
0
    def testMeasureMultiPolygon(self):
        # +-+-+ +-+-+
        # |   | |   |
        # + +-+ +-+ +
        # | |     | |
        # +-+     +-+
        polygon = QgsGeometry.fromMultiPolygonXY(
            [
                [[QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 2), QgsPointXY(0, 2), QgsPointXY(0, 0), ]],
                [[QgsPointXY(4, 0), QgsPointXY(5, 0), QgsPointXY(5, 2), QgsPointXY(3, 2), QgsPointXY(3, 1), QgsPointXY(4, 1), QgsPointXY(4, 0), ]]
            ]
        )

        da = QgsDistanceArea()
        area = da.measureArea(polygon)
        assert area == 6, 'Expected:\n%f\nGot:\n%f\n' % (6, area)

        perimeter = da.measurePerimeter(polygon)
        assert perimeter == 16, "Expected:\n%f\nGot:\n%f\n" % (16, perimeter)
Ejemplo n.º 22
0
 def find_geometry(self, g):
     if self.output_type == "Poly":
         stat = g.area()
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPolygonXY(g.asMultiPolygon())
         else:
             geometry = QgsGeometry.fromPolygonXY(g.asPolygon())
     elif self.output_type == "Line":
         stat = g.length()
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPolylineXY(g.asMultiPolyLine())
         else:
             geometry = QgsGeometry.fromPolyline(g.asPoly())
     else:
         stat = 1
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPointXY(g.asMultiPoint())
         else:
             geometry = QgsGeometry.fromPointXY(g.asPoint())
     return geometry, stat
def _swap_qgs_geometry(qgsgeom):
    if qgsgeom.wkbType() == QgsWkbTypes.Point:
        p = qgsgeom.asPoint()
        qgsgeom = QgsGeometry.fromPointXY(QgsPointXY(p[1], p[0]))
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPoint:
        mp = qgsgeom.asMultiPoint()
        qgsgeom = QgsGeometry.fromMultiPointXY([QgsPointXY(p[1], p[0]) for p in mp])
    elif qgsgeom.wkbType() == QgsWkbTypes.LineString:
        pl = qgsgeom.asPolyline()
        qgsgeom = QgsGeometry.fromPolylineXY([QgsPointXY(p[1],p[0]) for p in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiLineString:
        mls = qgsgeom.asMultiPolyline()
        qgsgeom = QgsGeometry.fromMultiPolylineXY([[QgsPointXY(p[1],p[0]) for p in pl] for pl in mls])
    elif qgsgeom.wkbType() == QgsWkbTypes.Polygon:
        pl = qgsgeom.asPolygon()
        qgsgeom = QgsGeometry.fromPolygonXY([[QgsPointXY(p[1],p[0]) for p in r] for r in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPolygon:
        mp = qgsgeom.asMultiPolygon()
        qgsgeom = QgsGeometry.fromMultiPolygonXY([[[QgsPointXY(p[1],p[0]) for p in r] for r in pl] for pl in mp])
    return qgsgeom
Ejemplo n.º 24
0
    def makeQgsPolygonFromBounds(self, xmin, ymin, xmax, ymax, isMulti=True):
        """
        Creating a polygon for the given coordinates
        """
        dx = (xmax - xmin) / 3
        dy = (ymax - ymin) / 3

        polyline = []

        point = QgsPointXY(xmin, ymin)
        polyline.append(point)
        point = QgsPointXY(xmin + dx, ymin)
        polyline.append(point)
        point = QgsPointXY(xmax - dx, ymin)
        polyline.append(point)
        point = QgsPointXY(xmax, ymin)
        polyline.append(point)
        point = QgsPointXY(xmax, ymin + dy)
        polyline.append(point)
        point = QgsPointXY(xmax, ymax - dy)
        polyline.append(point)
        point = QgsPointXY(xmax, ymax)
        polyline.append(point)
        point = QgsPointXY(xmax - dx, ymax)
        polyline.append(point)
        point = QgsPointXY(xmin + dx, ymax)
        polyline.append(point)
        point = QgsPointXY(xmin, ymax)
        polyline.append(point)
        point = QgsPointXY(xmin, ymax - dy)
        polyline.append(point)
        point = QgsPointXY(xmin, ymin + dy)
        polyline.append(point)
        point = QgsPointXY(xmin, ymin)
        polyline.append(point)

        if isMulti:
            qgsPolygon = QgsGeometry.fromMultiPolygonXY([[polyline]])
        else:
            qgsPolygon = QgsGeometry.fromPolygonXY([polyline])
        return qgsPolygon
Ejemplo n.º 25
0
 def current_layer_selection_changed(self):
     """PyqtSlot: When the selection of the current layer is changed"""
     if self.is_wrong_projection:
         self.projection_error()
         return
     selection = self.current_layer.selectedFeatures()
     if len(selection) == 0:
         self.le_external_id.setDisabled(True)
         self.le_area_title.setDisabled(True)
     elif len(selection) > 1:
         self.le_external_id.setDisabled(True)
         self.le_area_title.setDisabled(True)
         iface.messageBar().pushMessage(
             "INFO",
             "More than one feature selected, please re-select.",
             level=Qgis.Info,
             duration=3)
     elif len(selection) == 1:
         new_geometry = selection[0].geometry()
         # error pops up if geometry type is not polygon or multipolygon
         if new_geometry.wkbType() not in [
                 QgsWkbTypes.Polygon, QgsWkbTypes.MultiPolygon
         ]:
             self.error_dialog = ErrorDialog()
             self.error_dialog.fill_report(
                 "\n -------------------- WRONG GEOMETRY TYPE ------"
                 "-------------- \n\nInserted capture source area "
                 "should be either polygon or multipolygon.")
             self.error_dialog.show()
             return
         self.le_external_id.setEnabled(True)
         self.le_area_title.setEnabled(True)
         # convert to correct format
         if new_geometry.wkbType() == QgsWkbTypes.Polygon:
             new_geometry = QgsGeometry.fromMultiPolygonXY(
                 [new_geometry.asPolygon()])
         wkt = new_geometry.asWkt()
         sql = general_select.convert_geometry
         result = self.db.execute_return(sql, (wkt, ))
         self.geom = result.fetchall()[0][0]
Ejemplo n.º 26
0
 def buildQgsMultipolygon(self,polygon):
     '''
     Construct QgsMultiPolygon from matplotlib version
     '''
     mpoly=[]
     invalid=0
     for path in polygon.get_paths():
         path.should_simplify = False
         poly = path.to_polygons()
         if len(poly) < 1:
             continue
         if len(poly[0]) < 3:
             # Have had one vertix polygon from matplotlib!
             continue
         polypts=[[QgsPointXY(x,y) for x,y in p]
              for p in poly if len(p) > 3 ]
         mpoly.append(polypts)
     geom = None
     if len(mpoly) > 0:
         geom=QgsGeometry.fromMultiPolygonXY(mpoly)
         geom=geom.makeValid()
     return geom
Ejemplo n.º 27
0
 def creator_feature_added(self, qgsfId):
     """
        Called when feature is added
        @param qgsfId:      Id of added feature
        @type  qgsfId:      qgis.core.QgsFeature.QgsFeatureId
     """
     if qgsfId not in self.added_building_ids:
         self.added_building_ids.append(qgsfId)
     # get new feature geom
     request = QgsFeatureRequest().setFilterFid(qgsfId)
     new_feature = next(self.capture_source_area.getFeatures(request))
     new_geometry = new_feature.geometry()
     # convert to correct format
     if new_geometry.wkbType() == QgsWkbTypes.Polygon:
         new_geometry = QgsGeometry.fromMultiPolygonXY(
             [new_geometry.asPolygon()])
     wkt = new_geometry.asWkt()
     sql = general_select.convert_geometry
     result = self.db.execute_return(sql, (wkt, ))
     self.geom = result.fetchall()[0][0]
     self.le_area_title.setEnabled(True)
     self.le_external_id.setEnabled(True)
Ejemplo n.º 28
0
 def buildQgsMultipolygon(self,polygon):
     '''
     Construct QgsMultiPolygon from matplotlib version
     '''
     mpoly=[]
     invalid=0
     for path in polygon.get_paths():
         path.should_simplify = False
         poly = path.to_polygons()
         if len(poly) < 1:
             continue
         if len(poly[0]) < 3:
             # Have had one vertix polygon from matplotlib!
             continue
         polypts=[[QgsPointXY(x,y) for x,y in p]
              for p in poly if len(p) > 3 ]
         mpoly.append(polypts)
     geom = None
     if len(mpoly) > 0:
         geom=QgsGeometry.fromMultiPolygonXY(mpoly)
         geom=geom.makeValid()
     return geom
Ejemplo n.º 29
0
 def inv_vertex_order(self, geom):
     if geom.type() == 1:  #Line
         if geom.isMultipart():
             linhas = geom.asMultiPolyline()
             newLines = []
             for linha in linhas:
                 newLine = linha[::-1]
                 newLines += [newLine]
             newGeom = QgsGeometry.fromMultiPolylineXY(newLines)
             return newGeom
         else:
             linha = geom.asPolyline()
             newLine = linha[::-1]
             newGeom = QgsGeometry.fromPolylineXY(newLine)
             return newGeom
     elif geom.type() == 2:  #Polygon
         if geom.isMultipart():
             poligonos = geom.asMultiPolygon()
             newPolygons = []
             for pol in poligonos:
                 newPol = []
                 for anel in pol:
                     newAnel = anel[::-1]
                     newPol += [newAnel]
                 newPolygons += [newPol]
             newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons)
             return newGeom
         else:
             pol = geom.asPolygon()
             newPol = []
             for anel in pol:
                 newAnel = anel[::-1]
                 newPol += [newAnel]
             newGeom = QgsGeometry.fromPolygonXY(newPol)
             return newGeom
     else:
         return None
def processPoly(source, sink, feedback, maxseglen):
    layercrs = source.sourceCrs()
    if layercrs != epsg4326:
        transto4326 = QgsCoordinateTransform(layercrs, epsg4326,
                                             QgsProject.instance())
        transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs,
                                               QgsProject.instance())

    total = 100.0 / source.featureCount() if source.featureCount() else 0
    iterator = source.getFeatures()
    num_bad = 0
    for cnt, feature in enumerate(iterator):
        if feedback.isCanceled():
            break
        try:
            if not feature.geometry().isMultipart():
                poly = feature.geometry().asPolygon()
                numpolygons = len(poly)
                if numpolygons < 1:
                    continue

                ptset = []
                # Iterate through all points in the polygon and if the distance
                # is greater than the maxseglen, then add additional points.
                for points in poly:
                    numpoints = len(points)
                    if numpoints < 2:
                        continue
                    # If the input is not 4326 we need to convert it to that and then back to the output CRS
                    ptStart = QgsPointXY(points[0][0], points[0][1])
                    if layercrs != epsg4326:  # Convert to 4326
                        ptStart = transto4326.transform(ptStart)
                    pts = [ptStart]
                    for x in range(1, numpoints):
                        ptEnd = QgsPointXY(points[x][0], points[x][1])
                        if layercrs != epsg4326:  # Convert to 4326
                            ptEnd = transto4326.transform(ptEnd)
                        l = geod.InverseLine(ptStart.y(), ptStart.x(),
                                             ptEnd.y(), ptEnd.x())
                        # Check to see if the distance is greater than the maximum
                        # segment length and if so lets add additional points.
                        if l.s13 > maxseglen:
                            n = int(math.ceil(l.s13 / maxseglen))
                            seglen = l.s13 / n
                            for i in range(1, n):
                                s = seglen * i
                                g = l.Position(
                                    s, Geodesic.LATITUDE | Geodesic.LONGITUDE
                                    | Geodesic.LONG_UNROLL)
                                pts.append(QgsPointXY(g['lon2'], g['lat2']))
                        pts.append(ptEnd)
                        ptStart = ptEnd

                    if layercrs != epsg4326:  # Convert each point to the output CRS
                        for x, pt in enumerate(pts):
                            pts[x] = transfrom4326.transform(pt)
                    ptset.append(pts)

                if len(ptset) > 0:
                    featureout = QgsFeature()
                    featureout.setGeometry(QgsGeometry.fromPolygonXY(ptset))

                    featureout.setAttributes(feature.attributes())
                    sink.addFeature(featureout)
            else:
                multipoly = feature.geometry().asMultiPolygon()
                multiset = []
                for poly in multipoly:
                    ptset = []
                    for points in poly:
                        numpoints = len(points)
                        if numpoints < 2:
                            continue
                        # If the input is not 4326 we need to convert it to that and then back to the output CRS
                        ptStart = QgsPointXY(points[0][0], points[0][1])
                        if layercrs != epsg4326:  # Convert to 4326
                            ptStart = transto4326.transform(ptStart)
                        pts = [ptStart]
                        for x in range(1, numpoints):
                            ptEnd = QgsPointXY(points[x][0], points[x][1])
                            if layercrs != epsg4326:  # Convert to 4326
                                ptEnd = transto4326.transform(ptEnd)
                            l = geod.InverseLine(ptStart.y(), ptStart.x(),
                                                 ptEnd.y(), ptEnd.x())
                            if l.s13 > maxseglen:
                                n = int(math.ceil(l.s13 / maxseglen))
                                seglen = l.s13 / n
                                for i in range(1, n):
                                    s = seglen * i
                                    g = l.Position(
                                        s,
                                        Geodesic.LATITUDE | Geodesic.LONGITUDE
                                        | Geodesic.LONG_UNROLL)
                                    pts.append(QgsPointXY(
                                        g['lon2'], g['lat2']))
                            pts.append(ptEnd)
                            ptStart = ptEnd

                        if layercrs != epsg4326:  # Convert each point to the output CRS
                            for x, pt in enumerate(pts):
                                pts[x] = transfrom4326.transform(pt)
                        ptset.append(pts)
                    multiset.append(ptset)

                if len(multiset) > 0:
                    featureout = QgsFeature()
                    featureout.setGeometry(
                        QgsGeometry.fromMultiPolygonXY(multiset))

                    featureout.setAttributes(feature.attributes())
                    sink.addFeature(featureout)
        except:
            num_bad += 1
            '''s = traceback.format_exc()
            feedback.pushInfo(s)'''

        feedback.setProgress(int(cnt * total))
    return num_bad
Ejemplo n.º 31
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        # Retrieve the feature source and sink. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        source = self.parameterAsSource(parameters, self.INPUT, context)
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, source.fields(),
                                               source.wkbType(),
                                               source.sourceCrs())

        # Compute the number of steps to display within the progress bar and
        # get features from source
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        features = source.getFeatures()
        print(features)

        for current, feature in enumerate(features):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break
            # sshuair begin
            geom = feature.geometry()
            attrs = feature.attributes()
            geom_type = geom.wkbType()

            feature_new = QgsFeature()

            # Point
            if geom_type == 1:
                vertices = geom.asPoint()
                vert_new = bd2gcj(vertices[0], vertices[1])
                feature_new.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(vert_new[0], vert_new[1])))

            # LineString
            elif geom_type == 2:
                vert_new = []
                vertices = geom.asPolyline()
                for pt in vertices:
                    pt_new = bd2gcj(pt[0], pt[1])
                    vert_new.append(QgsPointXY(pt_new[0], pt_new[1]))
                feature_new.setGeometry(QgsGeometry.fromPolylineXY(vert_new))

            # Polygon
            elif geom_type == 3:
                vertices = geom.asPolygon()
                vert_new = []
                for ring in vertices:
                    ring_vert = []
                    for pt in ring:
                        pt_new = bd2gcj(pt[0], pt[1])
                        ring_vert.append(QgsPointXY(pt_new[0], pt_new[1]))
                    vert_new.append(ring_vert)
                feature_new.setGeometry(QgsGeometry.fromPolygonXY(vert_new))

            # MultiPoint
            elif geom_type == 4:
                vert_new = []
                vertices = geom.asMultiPoint()
                for pt in vertices:
                    pt_new = bd2gcj(pt[0], pt[1])
                    vert_new.append(QgsPointXY(pt_new[0], pt_new[1]))
                feature_new.setGeometry(QgsGeometry.fromMultiPointXY(vert_new))

            # MultiLineString
            elif geom_type == 5:
                vertices = geom.asMultiPolyline()
                vert_new = []
                for part in vertices:
                    linestring = []
                    for pt in part:
                        pt_new = bd2gcj(pt[0], pt[1])
                        linestring.append(QgsPointXY(pt_new[0], pt_new[1]))
                    vert_new.append(linestring)
                feature_new.setGeometry(
                    QgsGeometry.fromMultiPolylineXY(vert_new))

            # MultiPolygon
            elif geom_type == 6:
                vertices = geom.asMultiPolygon()
                vert_new = []
                for part in vertices:
                    poly = []
                    for ring in part:
                        ring_vert = []
                        for pt in ring:
                            pt_new = bd2gcj(pt[0], pt[1])
                            ring_vert.append(QgsPointXY(pt_new[0], pt_new[1]))
                        poly.append(ring_vert)
                    vert_new.append(poly)
                feature_new.setGeometry(
                    QgsGeometry.fromMultiPolygonXY(vert_new))
            else:
                continue

            feature_new.setAttributes(attrs)
            # sshuair end

            # feature = feature+0.1
            # Add a feature in the sink
            sink.addFeature(feature_new, QgsFeatureSink.FastInsert)

            # Update the progress bar
            feedback.setProgress(int(current * total))
            print(feature)

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: dest_id}
Ejemplo n.º 32
0
 def splitPolygonXY(self, geom):
     return QgsGeometry.fromMultiPolygonXY(list(self._splitPolygon(geom)))
Ejemplo n.º 33
0
count = Polygons.featureCount()
(sink, Biggest_parts) = self.parameterAsSink(parameters, 'Biggest parts',
                                             context, Polygons.fields(),
                                             QgsWkbTypes.MultiPolygon,
                                             Polygons.sourceCrs())

for n, feat in enumerate(Polygons.getFeatures()):
    if feedback.isCanceled():
        break
    feedback.setProgress(int(100 * n / count))

    geom = feat.geometry()
    if geom.isMultipart():
        features = feat
        geoms = geom.asGeometryCollection()
        geomarea = [(i, geoms[i].area()) for i in range(len(geoms))]
        geomarea.sort(key=itemgetter(1))
        if To_keep == 1:
            features.setGeometry(geoms[geomarea[-1][0]])
        elif To_keep > len(geoms):
            features.setGeometry(geom)
        else:
            features.setGeometry(geom)
            geomres = [
                geoms[i].asPolygon() for i, a in geomarea[-1 * To_keep:]
            ]
            features.setGeometry(QgsGeometry.fromMultiPolygonXY(geomres))
        sink.addFeature(features)
    else:
        sink.addFeature(feat)
Ejemplo n.º 34
0
    feedback.pushInfo("'To keep' value has been modified to be at least 1.")
    To_keep = 1

count = Polygons.featureCount()
(sink, Biggest_parts) = self.parameterAsSink(parameters, 'Biggest parts', context,
                                             Polygons.fields(), QgsWkbTypes.MultiPolygon, Polygons.sourceCrs())


for n, feat in enumerate(Polygons.getFeatures()):
    if feedback.isCanceled():
        break
    feedback.setProgress(int(100 * n / count))

    geom = feat.geometry()
    if geom.isMultipart():
        features = feat
        geoms = geom.asGeometryCollection()
        geomarea = [(i, geoms[i].area()) for i in range(len(geoms))]
        geomarea.sort(key=itemgetter(1))
        if To_keep == 1:
            features.setGeometry(geoms[geomarea[-1][0]])
        elif To_keep > len(geoms):
            features.setGeometry(geom)
        else:
            features.setGeometry(geom)
            geomres = [geoms[i].asPolygon() for i, a in geomarea[-1 * To_keep:]]
            features.setGeometry(QgsGeometry.fromMultiPolygonXY(geomres))
        sink.addFeature(features)
    else:
        sink.addFeature(feat)
Ejemplo n.º 35
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        earthRadius = 6370997
        
        # Retrieve the feature source and sink. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        source = self.parameterAsVectorLayer(
            parameters,
            self.INPUT,
            context
        )
        
        #lat
        centerLatitude = self.parameterAsDouble(
            parameters,
            self.CENTER_LATITUDE,
            context
        )
        
        #lon
        centerLongitude = self.parameterAsDouble(
            parameters,
            self.CENTER_LONGITUDE,
            context
        )
        
        #segment
        segments = self.parameterAsInt(
            parameters,
            self.SEGMENTS,
            context
        )
        

        # If source was not found, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSourceError method to return a standard
        # helper text for when a source cannot be evaluated
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
        
        if centerLatitude is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.CENTER_LATITUDE))
        
        if centerLongitude is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.CENTER_LATITUDE))
        
        if segments is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.SEGMENTS))

        output = self.parameterAsOutputLayer(
            parameters,
            self.OUTPUT,
            context
        )
        
        # Send some information to the user
        if source.sourceCrs().authid() != 'EPSG:4326':
            feedback.pushDebugInfo('Input layer for "Clip to Hemisphere" does not use the WGS84 (EPSG:4326) CRS. This can cause unexpected results.')
        else:
            feedback.pushInfo('CRS is {}'.format(source.sourceCrs().authid()))
            
        sourceCrs = source.sourceCrs()
        targetProjString = "+proj=ortho +lat_0=" + str(centerLatitude) + \
            " +lon_0=" + str(centerLongitude) + \
            " +x_0=0 +y_0=0 +a=" + str(earthRadius) + \
            " +b=" + str(earthRadius) + \
            " +units=m +no_defs"
        targetCrs = QgsCoordinateReferenceSystem()
        targetCrs.createFromProj4(targetProjString)
        
        transformTargetToSrc = QgsCoordinateTransform(targetCrs,sourceCrs,QgsProject.instance())
        transformSrcToTarget = QgsCoordinateTransform(sourceCrs,targetCrs,QgsProject.instance())
        
        clipLayer = QgsVectorLayer("MultiPolygon?crs=epsg:4326", "clipLayer", "memory")
        pr = clipLayer.dataProvider()
        
        """
        This part was adapted from (C) 2016 by Juernjakob Dugge
        Source: https://plugins.qgis.org/plugins/ClipToHemisphere/
        """
        # Handle edge cases:
        # Hemisphere centered on the equator
        if centerLatitude == 0:
            # Hemisphere centered on the equator and including the antimeridian
            if abs(centerLongitude) >= 90:
                edgeEast = -180 - np.sign(centerLongitude) * \
                        (180 - abs(centerLongitude)) + 90
                edgeWest = 180 - np.sign(centerLongitude) * \
                        (180 - abs(centerLongitude)) - 90
                circlePoints = [[
                    [QgsPointXY(-180.01, latitude) for
                        latitude in np.linspace(90, -90, segments / 8)] +
                    [QgsPointXY(longitude, -90) for longitude in
                        np.linspace(-180, edgeEast, segments / 8)] +
                    [QgsPointXY(edgeEast, latitude) for latitude in
                        np.linspace(-90, 90, segments / 8)] +
                    [QgsPointXY(longitude, 90) for longitude in
                        np.linspace(edgeEast, -180, segments / 8)]
                    ],
                    [
                    [QgsPointXY(edgeWest, latitude) for latitude in
                        np.linspace(90, -90, segments / 8)] +
                    [QgsPointXY(longitude, -90) for longitude in
                        np.linspace(edgeWest, 180, segments / 8)] +
                    [QgsPointXY(180.01, latitude) for
                        latitude in np.linspace(-90, 90, segments / 8)] +
                    [QgsPointXY(longitude, 90) for longitude in
                        np.linspace(180, edgeWest, segments / 8)]
                    ]]
            # Hemisphere centered on the equator not including the antimeridian
            else:
                edgeWest = centerLongitude - 90
                edgeEast = centerLongitude + 90
                circlePoints = [[
                    [QgsPointXY(edgeWest, latitude) for latitude in
                        np.linspace(90, -90, segments / 4)] +
                    [QgsPointXY(longitude, -90) for longitude in
                        np.linspace(edgeWest, edgeEast, segments / 4)] +
                    [QgsPointXY(edgeEast, latitude) for
                        latitude in np.linspace(-90, 90, segments / 4)] +
                    [QgsPointXY(longitude, 90) for longitude in
                        np.linspace(edgeEast, edgeWest, segments / 4)]
                    ]]
        # Hemisphere centered on one of the poles
        elif abs(centerLatitude) == 90:
            circlePoints = [[
                [QgsPointXY(-180.01, latitude) for latitude in
                        np.linspace(45 + 0.5 * centerLatitude,
                                   -45 + 0.5 * centerLatitude,
                                   segments / 4)] +
                [QgsPointXY(longitude, -45 + 0.5 * centerLatitude)
                        for longitude in
                        np.linspace(-180, 180, segments / 4)] +
                [QgsPointXY(180.01, latitude) for latitude in
                        np.linspace(-45 + 0.5 * centerLatitude,
                                     45 + 0.5 * centerLatitude,
                                   segments / 4)] +
                [QgsPointXY(longitude, 45 + 0.5 * centerLatitude) for longitude in
                        np.linspace(180, -180, segments / 4)]
                ]]
        # All other hemispheres
        else:
            # Create a circle in the orthographic projection, convert the
            # circle coordinates to the source CRS
            angles = np.linspace(0, 2 * np.pi, segments, endpoint=False)
            circlePoints = np.array([
                transformTargetToSrc.transform(
                    QgsPointXY(np.cos(angle) * earthRadius * 0.9999,
                             np.sin(angle) * earthRadius * 0.9999)
                            ) for angle in angles
            ])

            # Sort the projected circle coordinates from west to east
            sortIdx = np.argsort(circlePoints[:, 0])
            circlePoints = circlePoints[sortIdx, :]
            circlePoints = [[[QgsPointXY(point[0], point[1])
                for point in circlePoints]]]

            # Find the circle point in the orthographic projection that lies
            # on the antimeridian by linearly interpolating the angles of the
            # first and last coordinates
            startGap = 180 + circlePoints[0][0][0][0]
            endGap = 180 - circlePoints[0][0][-1][0]
            totalGap = startGap + endGap
            startCoordinates = transformSrcToTarget.transform(circlePoints[0][0][0])
            endCoordinates = transformSrcToTarget.transform(circlePoints[0][0][-1])
            startAngle = np.arctan2(startCoordinates[0], startCoordinates[1])
            endAngle = np.arctan2(endCoordinates[0], endCoordinates[1])
            antimeridianAngle = cmath.phase(
                endGap / totalGap * cmath.rect(1, startAngle) +
                startGap / totalGap * cmath.rect(1, endAngle))
            antimeridianPoint = transformTargetToSrc.transform(QgsPointXY(
                np.sin(antimeridianAngle) * earthRadius * 0.9999,
                np.cos(antimeridianAngle) * earthRadius * 0.9999
                ))

            # Close the polygon
            circlePoints[0][0].extend(
                [QgsPointXY(180.01, latitude) for latitude in
                        np.linspace(antimeridianPoint[1],
                            np.sign(centerLatitude) * 90, segments / 4)] +
                [QgsPointXY(-180.01, latitude) for latitude in
                        np.linspace(np.sign(centerLatitude) * 90,
                            antimeridianPoint[1], segments / 4)]
                )
        
        # Create the feature and add it to the layer
        circle = QgsFeature()
        circle.setGeometry(QgsGeometry.fromMultiPolygonXY(circlePoints))

        pr.addFeatures([circle])
        pr.updateExtents()
        
        # We need to add the clipping layer to the layer list in order to be
        # able to use them with processing.runalg()
        clipLayerReg = QgsProject.instance().addMapLayer(clipLayer)
        
        # If sink was not created, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSinkError method to return a standard
        # helper text for when a sink cannot be evaluated
        if output is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
        
        #clip the layer
        processing.run("qgis:clip", 
            {'INPUT': source,
             'OVERLAY': clipLayerReg, 
             'OUTPUT':output},
            feedback = feedback,
            context = context)
        

        


        return {self.OUTPUT: output}
Ejemplo n.º 36
0
            def densify_poly(in_layer, pr):
                bad_geom = 0
                iterator = in_layer.getFeatures()
                # create empty feature to write to
                for feature in iterator:
                    try:
                        if feature.geometry().wkbType(
                        ) == QgsWkbTypes.LineString:
                            line_geom = feature.geometry().asPolyline()
                            geom_type = "LineString"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.MultiLineString:
                            multiline_geom = feature.geometry(
                            ).asMultiPolyline()
                            geom_type = "MultiLineString"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.Polygon:
                            poly_geom = feature.geometry().asPolygon()
                            geom_type = "Polygon"
                        elif feature.geometry().wkbType(
                        ) == QgsWkbTypes.MultiPolygon:
                            multipoly_geom = feature.geometry().asMultiPolygon(
                            )
                            geom_type = "MultiPolygon"
                        else:
                            bad_geom += 1
                    except:
                        bad_geom += 1

                    if geom_type == "LineString":
                        dense_points = []
                        point_count = len(line_geom)
                        start_pt = QgsPointXY(line_geom[0][0], line_geom[0][1])
                        dense_points.append(start_pt)
                        if self.inLayer.crs() != wgs84crs:
                            start_pt = transtowgs84.transform(start_pt)
                        for j in range(1, point_count):
                            end_pt = QgsPointXY(line_geom[j][0],
                                                line_geom[j][1])
                            if self.inLayer.crs() != wgs84crs:
                                end_pt = transtowgs84.transform(end_pt)
                            # create a geographiclib line object
                            line_object = self.geod.InverseLine(
                                start_pt.y(), start_pt.x(), end_pt.y(),
                                end_pt.x())
                            # determine how many densified segments there will be
                            if self.segmentMethod == 'count':
                                n = self.segmentCount
                            else:
                                n = int(
                                    math.ceil(line_object.s13 / self.spacing))
                            if line_object.s13 > self.spacing:
                                seglen = line_object.s13 / n
                                for k in range(1, n):
                                    s = seglen * k
                                    g = line_object.Position(
                                        s,
                                        Geodesic.LATITUDE | Geodesic.LONGITUDE
                                        | Geodesic.LONG_UNROLL)
                                    waypoint = QgsPointXY(g['lon2'], g['lat2'])
                                    if self.inLayer.crs() != wgs84crs:
                                        waypoint = transfromwgs84.transform(
                                            waypoint)
                                    dense_points.append(waypoint)
                                if self.inLayer.crs() != wgs84crs:
                                    end_pt = transfromwgs84.transform(end_pt)
                                dense_points.append(end_pt)
                            start_pt = end_pt

                    elif geom_type == "MultiLineString":
                        dense_features = []
                        for i in range(len(multiline_geom)):
                            dense_points = []
                            line = multiline_geom[i]
                            point_count = len(line)
                            start_pt = QgsPointXY(line[0][0], line[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(line[j][0], line[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    start_pt = transtowgs84.transform(start_pt)
                                    end_pt = transtowgs84.transform(end_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt
                            dense_features.append(dense_points)

                    elif geom_type == "Polygon":
                        for poly in poly_geom:
                            dense_points = []
                            point_count = len(poly)
                            start_pt = QgsPointXY(poly[0][0], poly[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(poly[j][0], poly[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    end_pt = transtowgs84.transform(end_pt)
                                    start_pt = transtowgs84.transform(start_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt

                    if geom_type == "MultiPolygon":
                        dense_features = []
                        for i in range(len(multipoly_geom)):
                            dense_points = []
                            poly = multipoly_geom[i][0]
                            point_count = len(poly)
                            start_pt = QgsPointXY(poly[0][0], poly[0][1])
                            dense_points.append(start_pt)
                            for j in range(1, point_count):
                                end_pt = QgsPointXY(poly[j][0], poly[j][1])
                                if self.inLayer.crs() != wgs84crs:
                                    start_pt = transtowgs84.transform(start_pt)
                                    end_pt = transtowgs84.transform(end_pt)
                                # create a geographiclib line object
                                line_object = self.geod.InverseLine(
                                    start_pt.y(), start_pt.x(), end_pt.y(),
                                    end_pt.x())
                                # determine how many densified segments there will be
                                if self.segmentMethod == 'count':
                                    n = self.segmentCount
                                else:
                                    n = int(
                                        math.ceil(line_object.s13 /
                                                  self.spacing))
                                if line_object.s13 > self.spacing:
                                    seglen = line_object.s13 / n
                                    for k in range(1, n):
                                        s = seglen * k
                                        g = line_object.Position(
                                            s, Geodesic.LATITUDE
                                            | Geodesic.LONGITUDE
                                            | Geodesic.LONG_UNROLL)
                                        waypoint = QgsPointXY(
                                            g['lon2'], g['lat2'])
                                        if self.inLayer.crs() != wgs84crs:
                                            waypoint = transfromwgs84.transform(
                                                waypoint)
                                        dense_points.append(waypoint)
                                    if self.inLayer.crs() != wgs84crs:
                                        end_pt = transfromwgs84.transform(
                                            end_pt)
                                    dense_points.append(end_pt)
                                start_pt = end_pt
                            dense_features.append(dense_points)

                    new_poly = QgsFeature()
                    if geom_type == "LineString":
                        new_poly.setGeometry(
                            QgsGeometry.fromPolylineXY(dense_points))
                    elif geom_type == "MultiLineString":
                        new_poly.setGeometry(
                            QgsGeometry.fromMultiPolylineXY(dense_features))
                    elif geom_type == "Polygon":
                        new_poly.setGeometry(
                            QgsGeometry.fromPolygonXY([dense_points]))
                    elif geom_type == "MultiPolygon":
                        new_poly.setGeometry(
                            QgsGeometry.fromMultiPolygonXY([dense_features]))
                    new_poly.setAttributes(feature.attributes())
                    pr.addFeatures([new_poly])
                if bad_geom > 0:
                    self.iface.messageBar().pushWarning(
                        "", "{} features failed".format(bad_geom))