Exemplo n.º 1
0
    def generateFootprintsForFilmVertical(self):
        self.reloadFpLayer()
        self.reloadCpLayer()

        # Error wenn nur ein punkt vorhanden
        if self.cpLayer.featureCount() > 1:
            caps = self.fpLayer.dataProvider().capabilities()
            if caps & QgsVectorDataProvider.AddFeatures:
                #Get FORM1 from FilmInfoDict
                f1 = self.currentFilmInfoDict["form1"]  # Image height
                f2 = self.currentFilmInfoDict["form2"]  # Image width

                iterFeatures = self.cpLayer.getFeatures()
                iterNext = self.cpLayer.getFeatures()
                existingFootpints = QgsVectorLayerUtils.getValues(
                    self.fpLayer, "bildnummer")[0]
                ft = QgsFeature()
                ftNext = QgsFeature()
                iterNext.nextFeature(ftNext)
                fpFeats = []
                kappasToUpdate = {}
                # iterate over points from CP Layer > LON, LAT
                i = 0
                while iterFeatures.nextFeature(ft):
                    i += 1
                    iterNext.nextFeature(ftNext)
                    p = QgsPointXY(ft.geometry().asPoint())
                    if ft['bildnummer'] in existingFootpints:
                        pPrevGeom = QgsGeometry(ft.geometry())
                        #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD']))
                        continue
                    if i == 1:
                        pPrevGeom = QgsGeometry(ftNext.geometry())
                    #if iterNext.isClosed():
                    #    #use pPrev as pNext
                    #    pNext = QgsPoint(pPrev)
                    #else:
                    #    pNext = QgsPoint(ftNext.geometry().asPoint())

                    #kappa = p.azimuth(pPrev)

                    #kappa = p.azimuth(pNext)

                    # d = math.sqrt(2*((f1/2 * ft['MASS']/1000)**2))
                    d1 = f1 / 2 * ft['massstab'] / 1000
                    d2 = f2 / 2 * ft['massstab'] / 1000
                    #QMessageBox.warning(None, u"Bild Nummern", "{0}".format(d))

                    calcCrs = QgsCoordinateReferenceSystem()
                    calcCrs.createFromProj4(self.Proj4Utm(p))
                    ctF = QgsCoordinateTransform(self.cpLayer.crs(), calcCrs,
                                                 QgsProject.instance())

                    cpMetric = QgsGeometry(ft.geometry())
                    cpMetric.transform(ctF)
                    pPrevGeom.transform(ctF)
                    pMetric = QgsPointXY(cpMetric.asPoint())
                    pPrevMetric = QgsPointXY(pPrevGeom.asPoint())
                    kappaMetric = pMetric.azimuth(pPrevMetric)
                    pPrevGeom = QgsGeometry(ft.geometry())
                    left = pMetric.x() - d2
                    bottom = pMetric.y() - d1
                    right = pMetric.x() + d2
                    top = pMetric.y() + d1

                    #R = 6371
                    #D = (d/1000)
                    #cpLat = math.radians(p.y())
                    #cpLon = math.radians(p.x())
                    #urLat = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*math.cos(urBrng) )
                    #urLon = cpLon + math.atan2(math.sin(urBrng)*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(urLat))

                    #top = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R) )
                    #bottom = math.asin( math.sin(cpLat)*math.cos(D/R) + math.cos(cpLat)*math.sin(D/R)*-1 )

                    #lat = math.asin( math.sin(cpLat)*math.cos(D/R) )
                    #right = cpLon + math.atan2(math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat))
                    #left = cpLon + math.atan2(-1*math.sin(D/R)*math.cos(cpLat), math.cos(D/R)-math.sin(cpLat)*math.sin(lat))

                    #QMessageBox.warning(None, u"Bild Nummern", "{0}, {1}, {2}, {3}".format(math.degrees(top), math.degrees(bottom), math.degrees(left), math.degrees(right)))

                    #rect = QgsRectangle(math.degrees(left), math.degrees(bottom), math.degrees(right), math.degrees(top))
                    #l = math.degrees(left)
                    #b = math.degrees(bottom)
                    #r = math.degrees(right)
                    #t = math.degrees(top)
                    p1 = QgsGeometry.fromPointXY(QgsPointXY(left, bottom))
                    p2 = QgsGeometry.fromPointXY(QgsPointXY(right, bottom))
                    p3 = QgsGeometry.fromPointXY(QgsPointXY(right, top))
                    p4 = QgsGeometry.fromPointXY(QgsPointXY(left, top))
                    #p1.rotate(kappa+90, p)
                    #p2.rotate(kappa+90, p)
                    #p3.rotate(kappa+90, p)
                    #p4.rotate(kappa+90, p)
                    pol = [[
                        p1.asPoint(),
                        p2.asPoint(),
                        p3.asPoint(),
                        p4.asPoint()
                    ]]
                    geom = QgsGeometry.fromPolygonXY(pol)
                    geom.rotate(kappaMetric, pMetric)
                    #Transform to DestinationCRS
                    ctB = QgsCoordinateTransform(calcCrs, self.fpLayer.crs(),
                                                 QgsProject.instance())
                    geom.transform(ctB)

                    feat = QgsFeature(self.fpLayer.fields())
                    feat.setGeometry(geom)
                    feat.setAttribute('filmnummer', self.currentFilmNumber)
                    feat.setAttribute('bildnummer', ft['bildnummer'])
                    da = QgsDistanceArea()
                    da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym())
                    feat.setAttribute('shape_length',
                                      da.measurePerimeter(geom))
                    feat.setAttribute('shape_area', da.measureArea(geom))
                    fpFeats.append(feat)

                    # update Kappa in cpLayer
                    kappasToUpdate[ft.id()] = {
                        ft.fieldNameIndex('kappa'): kappaMetric
                    }

                iterFeatures.close()
                iterNext.close()

                resCAVs = self.cpLayer.dataProvider().changeAttributeValues(
                    kappasToUpdate)
                QgsMessageLog.logMessage(
                    f"Kappa Update for {kappasToUpdate}, Success: {resCAVs}",
                    tag="APIS",
                    level=Qgis.Success if resCAVs else Qgis.Critical)

                (res,
                 outFeats) = self.fpLayer.dataProvider().addFeatures(fpFeats)

                self.fpLayer.updateExtents()
                if self.canvas.isCachingEnabled():
                    self.fpLayer.triggerRepaint()
                else:
                    self.canvas.refresh()
            else:
                #Caps
                QMessageBox.warning(None, "Layer Capabilities!",
                                    "Layer Capabilities!")
        else:
            #small feature count
            QMessageBox.warning(
                None, "Footprints",
                "Zum Berechnen der senkrecht Footprint müssen mindestens zwei Bilder kartiert werden!"
            )
Exemplo n.º 2
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        output_file = self.parameterAsFileOutput(parameters,
                                                 self.OUTPUT_HTML_FILE,
                                                 context)

        spatialIndex = QgsSpatialIndex(source, feedback)

        distance = QgsDistanceArea()
        distance.setSourceCrs(source.sourceCrs(), context.transformContext())
        distance.setEllipsoid(context.project().ellipsoid())

        sumDist = 0.00
        A = source.sourceExtent()
        A = float(A.width() * A.height())

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

            neighbourID = spatialIndex.nearestNeighbor(
                feat.geometry().asPoint(), 2)[1]
            request = QgsFeatureRequest().setFilterFid(
                neighbourID).setSubsetOfAttributes([])
            neighbour = next(source.getFeatures(request))
            sumDist += distance.measureLine(neighbour.geometry().asPoint(),
                                            feat.geometry().asPoint())

            feedback.setProgress(int(current * total))

        do = float(sumDist) / count
        de = float(0.5 / math.sqrt(count / A))
        d = float(do / de)
        SE = float(0.26136 / math.sqrt(count**2 / A))
        zscore = float((do - de) / SE)

        results = {}
        results[self.OBSERVED_MD] = do
        results[self.EXPECTED_MD] = de
        results[self.NN_INDEX] = d
        results[self.POINT_COUNT] = count
        results[self.Z_SCORE] = zscore

        if output_file:
            data = []
            data.append('Observed mean distance: ' + str(do))
            data.append('Expected mean distance: ' + str(de))
            data.append('Nearest neighbour index: ' + str(d))
            data.append('Number of points: ' + str(count))
            data.append('Z-Score: ' + str(zscore))
            self.createHTML(output_file, data)
            results[self.OUTPUT_HTML_FILE] = output_file

        return results
Exemplo n.º 3
0
    def processAlgorithm(self, parameters, context, feedback):
        if parameters[self.INPUT] == parameters[self.HUBS]:
            raise QgsProcessingException(
                self.tr('Same layer given for both hubs and spokes'))

        point_source = self.parameterAsSource(parameters, self.INPUT, context)
        if point_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        hub_source = self.parameterAsSource(parameters, self.HUBS, context)
        if hub_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.HUBS))

        fieldName = self.parameterAsString(parameters, self.FIELD, context)

        units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT,
                                                context)]

        fields = point_source.fields()
        fields.append(QgsField('HubName', QVariant.String))
        fields.append(QgsField('HubDist', QVariant.Double))

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

        index = QgsSpatialIndex(
            hub_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(
                []).setDestinationCrs(point_source.sourceCrs(),
                                      context.transformContext())))

        distance = QgsDistanceArea()
        distance.setSourceCrs(point_source.sourceCrs(),
                              context.transformContext())
        distance.setEllipsoid(context.project().ellipsoid())

        # Scan source points, find nearest hub, and write to output file
        features = point_source.getFeatures()
        total = 100.0 / point_source.featureCount(
        ) if point_source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                sink.addFeature(f, QgsFeatureSink.FastInsert)
                continue
            src = f.geometry().boundingBox().center()

            neighbors = index.nearestNeighbor(src, 1)
            ft = next(
                hub_source.getFeatures(QgsFeatureRequest().setFilterFid(
                    neighbors[0]).setSubsetOfAttributes(
                        [fieldName], hub_source.fields()).setDestinationCrs(
                            point_source.sourceCrs(),
                            context.transformContext())))
            closest = ft.geometry().boundingBox().center()
            hubDist = distance.measureLine(src, closest)

            if units != self.LAYER_UNITS:
                hub_dist_in_desired_units = distance.convertLengthMeasurement(
                    hubDist, units)
            else:
                hub_dist_in_desired_units = hubDist

            attributes = f.attributes()
            attributes.append(ft[fieldName])
            attributes.append(hub_dist_in_desired_units)

            feat = QgsFeature()
            feat.setAttributes(attributes)

            feat.setGeometry(QgsGeometry.fromPolylineXY([src, closest]))

            sink.addFeature(feat, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 4
0
    def testAreaMeasureAndUnits(self):
        """Test a variety of area measurements in different CRS and ellipsoid modes, to check that the
           calculated areas and units are always consistent
        """

        da = QgsDistanceArea()
        da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(3452), QgsProject.instance().transformContext())
        da.setEllipsoid("NONE")

        polygon = QgsGeometry.fromPolygonXY(
            [[
                QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 2), QgsPointXY(0, 2), QgsPointXY(0, 0),
            ]]
        )

        # We check both the measured area AND the units, in case the logic regarding
        # ellipsoids and units changes in future
        area = da.measureArea(polygon)
        units = da.areaUnits()

        print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
        assert ((abs(area - 3.0) < 0.00000001 and units == QgsUnitTypes.AreaSquareDegrees) or
                (abs(area - 37176087091.5) < 0.1 and units == QgsUnitTypes.AreaSquareMeters))

        da.setEllipsoid("WGS84")
        area = da.measureArea(polygon)
        units = da.areaUnits()

        print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
        # should always be in Meters Squared
        self.assertAlmostEqual(area, 37416879192.9, delta=0.1)
        self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)

        # test converting the resultant area
        area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareMiles)
        self.assertAlmostEqual(area, 14446.7378, delta=0.001)

        # now try with a source CRS which is in feet
        polygon = QgsGeometry.fromPolygonXY(
            [[
                QgsPointXY(1850000, 4423000), QgsPointXY(1851000, 4423000), QgsPointXY(1851000, 4424000), QgsPointXY(1852000, 4424000), QgsPointXY(1852000, 4425000), QgsPointXY(1851000, 4425000), QgsPointXY(1850000, 4423000)
            ]]
        )
        da.setSourceCrs(QgsCoordinateReferenceSystem.fromSrsId(27469), QgsProject.instance().transformContext())
        da.setEllipsoid("NONE")
        # measurement should be in square feet
        area = da.measureArea(polygon)
        units = da.areaUnits()
        print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
        self.assertAlmostEqual(area, 2000000, delta=0.001)
        self.assertEqual(units, QgsUnitTypes.AreaSquareFeet)

        # test converting the resultant area
        area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
        self.assertAlmostEqual(area, 222222.2222, delta=0.001)

        da.setEllipsoid("WGS84")
        # now should be in Square Meters again
        area = da.measureArea(polygon)
        units = da.areaUnits()
        print(("measured {} in {}".format(area, QgsUnitTypes.toString(units))))
        self.assertAlmostEqual(area, 184149.37, delta=1.0)
        self.assertEqual(units, QgsUnitTypes.AreaSquareMeters)

        # test converting the resultant area
        area = da.convertAreaMeasurement(area, QgsUnitTypes.AreaSquareYards)
        self.assertAlmostEqual(area, 220240.8172549, delta=1.0)
Exemplo n.º 5
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER,
                                            context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE,
                                             context)

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

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

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        featureCount = source.featureCount()
        total = 100.0 / pointCount if pointCount else 1

        index = QgsSpatialIndex()
        points = dict()

        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())

        request = QgsFeatureRequest()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            if feedback.isCanceled():
                break

            # pick random feature
            fid = random.randint(0, featureCount - 1)
            f = next(
                source.getFeatures(
                    request.setFilterFid(fid).setSubsetOfAttributes([])))
            fGeom = f.geometry()

            if fGeom.isMultipart():
                lines = fGeom.asMultiPolyline()
                # pick random line
                lineId = random.randint(0, len(lines) - 1)
                vertices = lines[lineId]
            else:
                vertices = fGeom.asPolyline()

            # pick random segment
            if len(vertices) == 2:
                vid = 0
            else:
                vid = random.randint(0, len(vertices) - 2)
            startPoint = vertices[vid]
            endPoint = vertices[vid + 1]
            length = da.measureLine(startPoint, endPoint)
            dist = length * random.random()

            if dist > minDistance:
                d = dist / (length - dist)
                rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
                ry = (startPoint.y() + d * endPoint.y()) / (1 + d)

                # generate random point
                p = QgsPointXY(rx, ry)
                geom = QgsGeometry.fromPointXY(p)
                if vector.checkMinDistance(p, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    sink.addFeature(f, QgsFeatureSink.FastInsert)
                    index.insertFeature(f)
                    points[nPoints] = p
                    nPoints += 1
                    feedback.setProgress(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            feedback.pushInfo(
                self.tr(
                    'Could not generate requested number of random points. '
                    'Maximum number of attempts exceeded.'))

        return {self.OUTPUT: dest_id}
Exemplo n.º 6
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))

        group_field_name = self.parameterAsString(parameters, self.GROUP_FIELD, context)
        order_field_name = self.parameterAsString(parameters, self.ORDER_FIELD, context)
        date_format = self.parameterAsString(parameters, self.DATE_FORMAT, context)
        text_dir = self.parameterAsString(parameters, self.OUTPUT_TEXT_DIR, context)

        group_field_index = source.fields().lookupField(group_field_name)
        order_field_index = source.fields().lookupField(order_field_name)

        if group_field_index >= 0:
            group_field_def = source.fields().at(group_field_index)
        else:
            group_field_def = None
        order_field_def = source.fields().at(order_field_index)

        fields = QgsFields()
        if group_field_def is not None:
            fields.append(group_field_def)
        begin_field = QgsField(order_field_def)
        begin_field.setName('begin')
        fields.append(begin_field)
        end_field = QgsField(order_field_def)
        end_field.setName('end')
        fields.append(end_field)

        output_wkb = QgsWkbTypes.LineString
        if QgsWkbTypes.hasM(source.wkbType()):
            output_wkb = QgsWkbTypes.addM(output_wkb)
        if QgsWkbTypes.hasZ(source.wkbType()):
            output_wkb = QgsWkbTypes.addZ(output_wkb)

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

        points = dict()
        features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([group_field_index, order_field_index]), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                continue

            point = f.geometry().constGet().clone()
            if group_field_index >= 0:
                group = f.attributes()[group_field_index]
            else:
                group = 1
            order = f.attributes()[order_field_index]
            if date_format != '':
                order = datetime.strptime(str(order), date_format)
            if group in points:
                points[group].append((order, point))
            else:
                points[group] = [(order, point)]

            feedback.setProgress(int(current * total))

        feedback.setProgress(0)

        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())

        current = 0
        total = 100.0 / len(points) if points else 1
        for group, vertices in list(points.items()):
            if feedback.isCanceled():
                break

            vertices.sort(key=lambda x: (x[0] is None, x[0]))
            f = QgsFeature()
            attributes = []
            if group_field_index >= 0:
                attributes.append(group)
            attributes.extend([vertices[0][0], vertices[-1][0]])
            f.setAttributes(attributes)
            line = [node[1] for node in vertices]

            if text_dir:
                fileName = os.path.join(text_dir, '%s.txt' % group)

                with open(fileName, 'w') as fl:
                    fl.write('angle=Azimuth\n')
                    fl.write('heading=Coordinate_System\n')
                    fl.write('dist_units=Default\n')

                    for i in range(len(line)):
                        if i == 0:
                            fl.write('startAt=%f;%f;90\n' % (line[i].x(), line[i].y()))
                            fl.write('survey=Polygonal\n')
                            fl.write('[data]\n')
                        else:
                            angle = line[i - 1].azimuth(line[i])
                            distance = da.measureLine(QgsPointXY(line[i - 1]), QgsPointXY(line[i]))
                            fl.write('%f;%f;90\n' % (angle, distance))

            f.setGeometry(QgsGeometry(QgsLineString(line)))
            sink.addFeature(f, QgsFeatureSink.FastInsert)
            current += 1
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 7
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))

        layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
        field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
        field_type = self.TYPES[self.parameterAsEnum(parameters, self.FIELD_TYPE, context)]
        width = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)
        precision = self.parameterAsInt(parameters, self.FIELD_PRECISION, context)
        new_field = self.parameterAsBool(parameters, self.NEW_FIELD, context)
        formula = self.parameterAsString(parameters, self.FORMULA, context)

        expression = QgsExpression(formula)
        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())
        expression.setGeomCalculator(da)

        expression.setDistanceUnits(context.project().distanceUnits())
        expression.setAreaUnits(context.project().areaUnits())

        fields = source.fields()
        field_index = fields.lookupField(field_name)
        if new_field or field_index < 0:
            fields.append(QgsField(field_name, field_type, '', width, precision))

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

        exp_context = self.createExpressionContext(parameters, context)
        if layer is not None:
            exp_context.appendScope(QgsExpressionContextUtils.layerScope(layer))

        expression.prepare(exp_context)

        features = source.getFeatures()
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            rownum = current + 1
            exp_context.setFeature(f)
            exp_context.lastScope().setVariable("row_number", rownum)
            value = expression.evaluate(exp_context)
            if expression.hasEvalError():
                feedback.reportError(expression.evalErrorString())
            else:
                attrs = f.attributes()
                if new_field or field_index < 0:
                    attrs.append(value)
                else:
                    attrs[field_index] = value
                f.setAttributes(attrs)
                sink.addFeature(f, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 8
0
    def processAlgorithm(self, context, feedback):
        layer = self.getParameterValue(self.INPUT_LAYER)
        mapping = self.getParameterValue(self.FIELDS_MAPPING)
        output = self.getOutputFromName(self.OUTPUT_LAYER)

        layer = QgsProcessingUtils.mapLayerFromString(layer, context)
        fields = QgsFields()
        expressions = []

        da = QgsDistanceArea()
        da.setSourceCrs(layer.crs())
        da.setEllipsoid(QgsProject.instance().ellipsoid())

        exp_context = layer.createExpressionContext()

        for field_def in mapping:
            fields.append(
                QgsField(field_def['name'], field_def['type'],
                         field_def['length'], field_def['precision']))

            expression = QgsExpression(field_def['expression'])
            expression.setGeomCalculator(da)
            expression.setDistanceUnits(QgsProject.instance().distanceUnits())
            expression.setAreaUnits(QgsProject.instance().areaUnits())
            expression.prepare(exp_context)
            if expression.hasParserError():
                raise GeoAlgorithmExecutionException(
                    self.tr(u'Parser error in expression "{}": {}').format(
                        str(expression.expression()),
                        str(expression.parserErrorString())))
            expressions.append(expression)

        writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs(),
                                        context)

        # Create output vector layer with new attributes
        error_exp = None
        inFeat = QgsFeature()
        outFeat = QgsFeature()
        features = QgsProcessingUtils.getFeatures(layer, context)
        count = QgsProcessingUtils.featureCount(layer, context)
        if count > 0:
            total = 100.0 / count
            for current, inFeat in enumerate(features):
                rownum = current + 1

                geometry = inFeat.geometry()
                outFeat.setGeometry(geometry)

                attrs = []
                for i in range(0, len(mapping)):
                    field_def = mapping[i]
                    expression = expressions[i]
                    exp_context.setFeature(inFeat)
                    exp_context.lastScope().setVariable("row_number", rownum)
                    value = expression.evaluate(exp_context)
                    if expression.hasEvalError():
                        error_exp = expression
                        break

                    attrs.append(value)
                outFeat.setAttributes(attrs)

                writer.addFeature(outFeat)

                feedback.setProgress(int(current * total))
        else:
            feedback.setProgress(100)

        del writer

        if error_exp is not None:
            raise GeoAlgorithmExecutionException(
                self.tr(u'Evaluation error in expression "{}": {}').format(
                    str(error_exp.expression()),
                    str(error_exp.parserErrorString())))
Exemplo n.º 9
0
# -*- coding: utf-8 -*-
"""
Spyder Editor
"""

import xlwt
import time
start_time = time.perf_counter()
import pandas as pd
pd.set_option('display.max_columns', 500)
pd.set_option('display.width', 120)

from qgis.core import QgsDistanceArea, QgsPointXY
distance = QgsDistanceArea()
from pyproj import Transformer
transformer = Transformer.from_crs(
    "epsg:31467", "epsg:25832", always_xy=True
)  ##gauss_krueger_coordinate zone 3 (31467), UTM zone 32N (25832)

from pathlib import Path
f = open(Path.home() / 'python32' / 'python_dir.txt', mode='r')
path = Path.joinpath(Path(r'C:' + f.readline()), 'PT_data', 'VISUM_FAN.txt')
f = path.read_text().split('\n')

##connection to file
df_FAN = pd.read_excel(r'C:' + f[0], sheet_name=f[1])
df_VISUM = pd.read_excel(r'C:' + f[2], sheet_name=f[3])

wb = xlwt.Workbook()
ws = wb.add_sheet(f[5])
results = 'C:' + f[4]
Exemplo n.º 10
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        method = self.parameterAsEnum(parameters, self.METHOD, context)

        wkb_type = source.wkbType()
        fields = source.fields()

        new_fields = QgsFields()
        if QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.PolygonGeometry:
            new_fields.append(QgsField('area', QVariant.Double))
            new_fields.append(QgsField('perimeter', QVariant.Double))
        elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.LineGeometry:
            new_fields.append(QgsField('length', QVariant.Double))
        else:
            new_fields.append(QgsField('xcoord', QVariant.Double))
            new_fields.append(QgsField('ycoord', QVariant.Double))
            if QgsWkbTypes.hasZ(source.wkbType()):
                self.export_z = True
                new_fields.append(QgsField('zcoord', QVariant.Double))
            if QgsWkbTypes.hasM(source.wkbType()):
                self.export_m = True
                new_fields.append(QgsField('mvalue', QVariant.Double))

        fields = QgsProcessingUtils.combineFields(fields, new_fields)
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields, wkb_type,
                                               source.sourceCrs())

        coordTransform = None

        # Calculate with:
        # 0 - layer CRS
        # 1 - project CRS
        # 2 - ellipsoidal

        self.distance_area = QgsDistanceArea()
        if method == 2:
            self.distance_area.setSourceCrs(source.sourceCrs())
            self.distance_area.setEllipsoid(context.project().ellipsoid())
        elif method == 1:
            coordTransform = QgsCoordinateTransform(source.sourceCrs(),
                                                    context.project().crs())

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

            outFeat = f
            attrs = f.attributes()
            inGeom = f.geometry()
            if inGeom:
                if coordTransform is not None:
                    inGeom.transform(coordTransform)

                if inGeom.type() == QgsWkbTypes.PointGeometry:
                    attrs.extend(self.point_attributes(inGeom))
                elif inGeom.type() == QgsWkbTypes.PolygonGeometry:
                    attrs.extend(self.polygon_attributes(inGeom))
                else:
                    attrs.extend(self.line_attributes(inGeom))

            outFeat.setAttributes(attrs)
            sink.addFeature(outFeat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 11
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER))
        fieldName = self.getParameterValue(self.FIELD_NAME)
        fieldType = self.TYPES[self.getParameterValue(self.FIELD_TYPE)]
        width = self.getParameterValue(self.FIELD_LENGTH)
        precision = self.getParameterValue(self.FIELD_PRECISION)
        newField = self.getParameterValue(self.NEW_FIELD)
        formula = self.getParameterValue(self.FORMULA)

        output = self.getOutputFromName(self.OUTPUT_LAYER)

        if output.value == '':
            ext = output.getDefaultFileExtension(self)
            output.value = system.getTempFilenameInTempFolder(
                output.name + '.' + ext)

        provider = layer.dataProvider()
        fields = layer.pendingFields()
        if newField:
            fields.append(QgsField(fieldName, fieldType, '', width, precision))

        writer = output.getVectorWriter(fields, provider.geometryType(),
                                        layer.crs())

        exp = QgsExpression(formula)

        da = QgsDistanceArea()
        da.setSourceCrs(layer.crs().srsid())
        da.setEllipsoidalMode(
            iface.mapCanvas().mapSettings().hasCrsTransformEnabled())
        da.setEllipsoid(QgsProject.instance().readEntry(
            'Measure', '/Ellipsoid', GEO_NONE)[0])
        exp.setGeomCalculator(da)

        if not exp.prepare(layer.pendingFields()):
            raise GeoAlgorithmExecutionException(
                self.tr('Evaluation error: %s' % exp.evalErrorString()))

        outFeature = QgsFeature()
        outFeature.initAttributes(len(fields))
        outFeature.setFields(fields)

        error = ''
        calculationSuccess = True

        current = 0
        features = vector.features(layer)
        total = 100.0 / len(features)

        rownum = 1
        for current, f in enumerate(features):
            rownum = current + 1
            exp.setCurrentRowNumber(rownum)
            value = exp.evaluate(f)
            if exp.hasEvalError():
                calculationSuccess = False
                error = exp.evalErrorString()
                break
            else:
                outFeature.setGeometry(f.geometry())
                for fld in f.fields():
                    outFeature[fld.name()] = f[fld.name()]
                outFeature[fieldName] = value
                writer.addFeature(outFeature)

            progress.setPercentage(int(current * total))
        del writer

        if not calculationSuccess:
            raise GeoAlgorithmExecutionException(
                self.tr('An error occured while evaluating the calculation '
                        'string:\n%s' % error))
Exemplo n.º 12
0
    def processAlgorithm(self, parameters, context, feedback):
        # get input variables
        raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT,
                                                   context)
        band_number = self.parameterAsInt(parameters, self.BAND, context)
        output = self.parameterAsFileOutput(parameters, self.OUTPUT, context)

        # layer name
        name = raster_layer.name()

        # layer provider
        provider = raster_layer.dataProvider()

        # get CRS
        crs_raster = raster_layer.crs()

        # set project ellipsoid (for measurements) to CRS ellipsoid
        ellipsoid = context.project().crs().ellipsoidAcronym()

        # get transform context from project
        trans_context = context.project().transformContext()

        # 5% done
        feedback.setProgress(5)

        # Initialize Area calculator class with ellipsoid
        da = QgsDistanceArea()
        da.setSourceCrs(crs_raster, trans_context)
        da.setEllipsoid(ellipsoid)

        # get raster extent
        extent = raster_layer.extent()
        extent = QgsGeometry().fromRect(extent)

        # 20% done
        feedback.setProgress(20)

        # get area of extent
        feedback.pushConsoleInfo(
            self.tr(f'Measuring area of raster rectangle...'))
        area = da.measureArea(extent)

        # convert area from
        area_m2 = da.convertAreaMeasurement(area,
                                            QgsUnitTypes.AreaSquareMeters)

        # 30% done
        feedback.setProgress(30)

        # check if NoData value is set
        if provider.sourceHasNoDataValue(band_number):
            feedback.pushConsoleInfo(
                self.tr(f'Calculating NoData percentage...'))
            # unique values parameters
            rastervalue_params = {'INPUT': raster_layer, 'BAND': band_number}

            # run unique values
            result = processing.run('native:rasterlayeruniquevaluesreport',
                                    rastervalue_params)

            # get total pixel and nodata count
            cells = result['TOTAL_PIXEL_COUNT']
            nodata_cells = result['NODATA_PIXEL_COUNT']

            # calculate nodata percentage
            nodata_percentage = nodata_cells / cells

            # calclate data coverage
            feedback.pushConsoleInfo(
                self.tr(f'Calculating data coverage...\n'))
            coverage_m2 = area_m2 * (1 - nodata_percentage)
            coverage_percentage = (1 - nodata_percentage)
        else:
            feedback.reportError(self.tr(
                'Missing NoData value(s) detected. Check settings of the raster layer!'
            ),
                                 fatalError=False)
            coverage_m2 = area_m2
            coverage_percentage = 1.0

        # 80% done
        feedback.setProgress(80)

        # calculate area units
        area_km2 = area_m2 / (1000 * 1000)
        coverage_km2 = coverage_m2 / (1000 * 1000)

        feedback.pushConsoleInfo(
            self.tr(f'------------------------------------------\n'))

        feedback.pushConsoleInfo(
            self.tr(f'Raster Coverage of Layer [ {name} ]:\n'))

        feedback.pushConsoleInfo(
            self.tr(f'Raster Area [km2] ....... : {round(area_km2,3)}'))
        feedback.pushConsoleInfo(
            self.tr(f'Data Coverage [km2] ..... : {round(coverage_km2,3)}'))
        feedback.pushConsoleInfo(
            self.tr(f'Data Coverage [m2] ...... : {round(coverage_m2,2)}'))
        feedback.pushConsoleInfo(
            self.
            tr(f'Data Coverage [%] ....... : {round(coverage_percentage * 100,2)}\n'
               ))

        feedback.pushConsoleInfo(
            self.
            tr(f'This is {round(coverage_km2 / self.bremen_area,2)} times the area of Bremen\n'
               ))

        feedback.pushConsoleInfo(
            self.tr(f'------------------------------------------\n'))

        # 100% done
        feedback.setProgress(100)
        feedback.pushInfo(
            self.tr(
                f'{utils.return_success()}! Raster area has been calculated!\n'
            ))

        result = {
            self.RASTER_AREA_KM2: area_km2,
            self.DATA_COVERAGE_KM2: coverage_km2,
            self.DATA_COVERAGE_M2: coverage_m2,
            self.DATA_COVERAGE_PERCENT: coverage_percentage,
            self.OUTPUT: output
        }

        if output != '':
            self.write_output(name, result, output)

        return result
Exemplo n.º 13
0
    def processAlgorithm(self, progress):
        lineLayer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.LINES))
        polyLayer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.POLYGONS))
        lengthFieldName = self.getParameterValue(self.LEN_FIELD)
        countFieldName = self.getParameterValue(self.COUNT_FIELD)

        polyProvider = polyLayer.dataProvider()

        (idxLength,
         fieldList) = vector.findOrCreateField(polyLayer,
                                               polyLayer.pendingFields(),
                                               lengthFieldName)
        (idxCount,
         fieldList) = vector.findOrCreateField(polyLayer, fieldList,
                                               countFieldName)

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fieldList.toList(), polyProvider.geometryType(),
            polyProvider.crs())

        spatialIndex = vector.spatialindex(lineLayer)

        ftLine = QgsFeature()
        ftPoly = QgsFeature()
        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()
        distArea = QgsDistanceArea()

        current = 0
        features = vector.features(polyLayer)
        total = 100.0 / float(len(features))
        hasIntersections = False
        for ftPoly in features:
            inGeom = QgsGeometry(ftPoly.geometry())
            attrs = ftPoly.attributes()
            count = 0
            length = 0
            hasIntersections = False
            lines = spatialIndex.intersects(inGeom.boundingBox())
            if len(lines) > 0:
                hasIntersections = True

            if hasIntersections:
                for i in lines:
                    request = QgsFeatureRequest().setFilterFid(i)
                    ftLine = lineLayer.getFeatures(request).next()
                    tmpGeom = QgsGeometry(ftLine.geometry())
                    if inGeom.intersects(tmpGeom):
                        outGeom = inGeom.intersection(tmpGeom)
                        length += distArea.measure(outGeom)
                        count += 1

            outFeat.setGeometry(inGeom)
            if idxLength == len(attrs):
                attrs.append(length)
            else:
                attrs[idxLength] = length
            if idxCount == len(attrs):
                attrs.append(count)
            else:
                attrs[idxCount] = count
            outFeat.setAttributes(attrs)
            writer.addFeature(outFeat)

            current += 1
            progress.setPercentage(int(current * total))

        del writer
Exemplo n.º 14
0
    def generateFootprintsForFilmOblique(self):
        self.reloadFpLayer()
        self.reloadCpLayer()

        caps = self.fpLayer.dataProvider().capabilities()
        if caps & QgsVectorDataProvider.AddFeatures:
            if self.cpLayer.dataProvider().featureCount() > 0:
                iter = self.cpLayer.getFeatures()
                existingFootpints = QgsVectorLayerUtils.getValues(
                    self.fpLayer, "bildnummer")[0]
                cpFt = QgsFeature()
                fpFts = []
                #iterate over points from CP Layer > LON, LAT
                while iter.nextFeature(cpFt):
                    if cpFt['bildnummer'] in existingFootpints:
                        #QMessageBox.warning(None, u"Bild Nummern", u"Footprint für das Bild mit der Nummer {0} wurde bereits erstellt.".format(ft['BILD']))
                        continue
                    cp = cpFt.geometry()
                    cpMetric = QgsGeometry(cp)
                    destCrs = QgsCoordinateReferenceSystem()
                    destCrs.createFromProj4(self.Proj4Utm(cp.asPoint()))
                    coordTransformF = QgsCoordinateTransform(
                        self.cpLayer.crs(), destCrs, QgsProject.instance())
                    coordTransformB = QgsCoordinateTransform(
                        destCrs, self.cpLayer.crs(), QgsProject.instance())
                    cpMetric.transform(coordTransformF)
                    if cpFt['radius'] == '':
                        r = 175
                    else:
                        r = float(cpFt['radius'])
                    fpMetric = QgsGeometry(cpMetric.buffer(r, 18))
                    fp = QgsGeometry(fpMetric)
                    fp.transform(coordTransformB)

                    fpFt = QgsFeature(self.fpLayer.fields())
                    fpFt.setGeometry(fp)
                    fpFt.setAttribute("bildnummer", cpFt["bildnummer"])
                    fpFt.setAttribute("filmnummer", cpFt["filmnummer"])
                    da = QgsDistanceArea()
                    da.setEllipsoid(self.fpLayer.crs().ellipsoidAcronym())
                    fpFt.setAttribute('shape_length', da.measurePerimeter(fp))
                    fpFt.setAttribute('shape_area', da.measureArea(fp))
                    fpFts.append(fpFt)

                (res,
                 outFeats) = self.fpLayer.dataProvider().addFeatures(fpFts)
                self.fpLayer.updateExtents()
                if self.canvas.isCachingEnabled():
                    self.fpLayer.triggerRepaint()
                else:
                    self.canvas.refresh()
            else:
                QMessageBox.warning(
                    None, "Keine Bildmittelpunkte",
                    "Keine Bildmittelpunkte für den Film {0} vorhanden.".
                    format(self.currentFilmNumber))
        else:
            QMessageBox.warning(
                None, "Layer Capabilities",
                "AddFeature is not enabled ({0})".format(
                    self.fpLayer.dataProvider().capabilitiesString()))
Exemplo n.º 15
0
    def processAlgorithm(self, feedback):
        layerPoints = dataobjects.getObjectFromUri(
            self.getParameterValue(self.POINTS))
        layerHubs = dataobjects.getObjectFromUri(
            self.getParameterValue(self.HUBS))
        fieldName = self.getParameterValue(self.FIELD)

        addLines = self.getParameterValue(self.GEOMETRY)
        units = self.UNITS[self.getParameterValue(self.UNIT)]

        if layerPoints.source() == layerHubs.source():
            raise GeoAlgorithmExecutionException(
                self.tr('Same layer given for both hubs and spokes'))

        fields = layerPoints.fields()
        fields.append(QgsField('HubName', QVariant.String))
        fields.append(QgsField('HubDist', QVariant.Double))

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

        index = vector.spatialindex(layerHubs)

        distance = QgsDistanceArea()
        distance.setSourceCrs(layerPoints.crs().srsid())
        distance.setEllipsoidalMode(True)

        # Scan source points, find nearest hub, and write to output file
        features = vector.features(layerPoints)
        total = 100.0 / len(features)
        for current, f in enumerate(features):
            src = f.geometry().boundingBox().center()

            neighbors = index.nearestNeighbor(src, 1)
            ft = next(
                layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(
                    neighbors[0]).setSubsetOfAttributes([fieldName],
                                                        layerHubs.fields())))
            closest = ft.geometry().boundingBox().center()
            hubDist = distance.measureLine(src, closest)

            attributes = f.attributes()
            attributes.append(ft[fieldName])
            if units == 'Feet':
                attributes.append(hubDist * 3.2808399)
            elif units == 'Miles':
                attributes.append(hubDist * 0.000621371192)
            elif units == 'Kilometers':
                attributes.append(hubDist / 1000.0)
            elif units != 'Meters':
                attributes.append(
                    sqrt(
                        pow(src.x() - closest.x(), 2.0) +
                        pow(src.y() - closest.y(), 2.0)))
            else:
                attributes.append(hubDist)

            feat = QgsFeature()
            feat.setAttributes(attributes)

            feat.setGeometry(QgsGeometry.fromPoint(src))

            writer.addFeature(feat)
            feedback.setProgress(int(current * total))

        del writer
Exemplo n.º 16
0
    def processAlgorithm(self, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(
            self.getParameterValue(self.INPUT_LAYER), context)
        fieldName = self.getParameterValue(self.FIELD_NAME)
        fieldType = self.TYPES[self.getParameterValue(self.FIELD_TYPE)]
        width = self.getParameterValue(self.FIELD_LENGTH)
        precision = self.getParameterValue(self.FIELD_PRECISION)
        newField = self.getParameterValue(self.NEW_FIELD)
        formula = self.getParameterValue(self.FORMULA)

        output = self.getOutputFromName(self.OUTPUT_LAYER)

        fields = layer.fields()
        if newField:
            fields.append(QgsField(fieldName, fieldType, '', width, precision))

        writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs(),
                                        context)

        exp = QgsExpression(formula)

        da = QgsDistanceArea()
        da.setSourceCrs(layer.crs())
        da.setEllipsoid(QgsProject.instance().ellipsoid())
        exp.setGeomCalculator(da)
        exp.setDistanceUnits(QgsProject.instance().distanceUnits())
        exp.setAreaUnits(QgsProject.instance().areaUnits())

        exp_context = QgsExpressionContext(
            QgsExpressionContextUtils.globalProjectLayerScopes(layer))

        if not exp.prepare(exp_context):
            raise GeoAlgorithmExecutionException(
                self.tr('Evaluation error: {0}').format(exp.evalErrorString()))

        outFeature = QgsFeature()
        outFeature.initAttributes(len(fields))
        outFeature.setFields(fields)

        error = ''
        calculationSuccess = True

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

        rownum = 1
        for current, f in enumerate(features):
            rownum = current + 1
            exp_context.setFeature(f)
            exp_context.lastScope().setVariable("row_number", rownum)
            value = exp.evaluate(exp_context)
            if exp.hasEvalError():
                calculationSuccess = False
                error = exp.evalErrorString()
                break
            else:
                outFeature.setGeometry(f.geometry())
                for fld in f.fields():
                    outFeature[fld.name()] = f[fld.name()]
                outFeature[fieldName] = value
                writer.addFeature(outFeature)

            feedback.setProgress(int(current * total))
        del writer

        if not calculationSuccess:
            raise GeoAlgorithmExecutionException(
                self.tr('An error occurred while evaluating the calculation '
                        'string:\n{0}').format(error))
Exemplo n.º 17
0
    def regularMatrix(self, parameters, context, source, inField,
                      target_source, targetField, nPoints, feedback):

        distArea = QgsDistanceArea()
        distArea.setSourceCrs(source.sourceCrs(), context.transformContext())
        distArea.setEllipsoid(context.project().ellipsoid())

        inIdx = source.fields().lookupField(inField)
        targetIdx = target_source.fields().lookupField(targetField)

        index = QgsSpatialIndex(
            target_source.getFeatures(
                QgsFeatureRequest().setSubsetOfAttributes(
                    []).setDestinationCrs(source.sourceCrs(),
                                          context.transformContext())),
            feedback)

        first = True
        sink = None
        dest_id = None
        features = source.getFeatures(
            QgsFeatureRequest().setSubsetOfAttributes([inIdx]))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            inGeom = inFeat.geometry()
            if first:
                featList = index.nearestNeighbor(inGeom.asPoint(), nPoints)
                first = False
                fields = QgsFields()
                input_id_field = source.fields()[inIdx]
                input_id_field.setName('ID')
                fields.append(input_id_field)
                for f in target_source.getFeatures(
                        QgsFeatureRequest().setFilterFids(
                            featList).setSubsetOfAttributes([
                                targetIdx
                            ]).setDestinationCrs(source.sourceCrs(),
                                                 context.transformContext())):
                    fields.append(
                        QgsField(str(f[targetField]), QVariant.Double))

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

            data = [inFeat[inField]]
            for target in target_source.getFeatures(
                    QgsFeatureRequest().setSubsetOfAttributes(
                        []).setFilterFids(featList).setDestinationCrs(
                            source.sourceCrs(), context.transformContext())):
                if feedback.isCanceled():
                    break
                outGeom = target.geometry()
                dist = distArea.measureLine(inGeom.asPoint(),
                                            outGeom.asPoint())
                data.append(dist)

            out_feature = QgsFeature()
            out_feature.setGeometry(inGeom)
            out_feature.setAttributes(data)
            sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 18
0
    def processAlgorithm(self, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(
            self.getParameterValue(self.VECTOR), context)
        fieldName = self.getParameterValue(self.FIELD)
        minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
        strategy = self.getParameterValue(self.STRATEGY)

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QgsWkbTypes.Point, layer.crs(), context)

        da = QgsDistanceArea()

        features = QgsProcessingUtils.getFeatures(layer, context)
        for current, f in enumerate(features):
            fGeom = f.geometry()
            bbox = fGeom.boundingBox()
            if strategy == 0:
                pointCount = int(f[fieldName])
            else:
                pointCount = int(round(f[fieldName] * da.measureArea(fGeom)))

            if pointCount == 0:
                feedback.pushInfo(
                    "Skip feature {} as number of points for it is 0.")
                continue

            index = QgsSpatialIndex()
            points = dict()

            nPoints = 0
            nIterations = 0
            maxIterations = pointCount * 200
            total = 100.0 / pointCount

            random.seed()

            while nIterations < maxIterations and nPoints < pointCount:
                rx = bbox.xMinimum() + bbox.width() * random.random()
                ry = bbox.yMinimum() + bbox.height() * random.random()

                pnt = QgsPoint(rx, ry)
                geom = QgsGeometry.fromPoint(pnt)
                if geom.within(fGeom) and \
                   vector.checkMinDistance(pnt, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    writer.addFeature(f)
                    index.insertFeature(f)
                    points[nPoints] = pnt
                    nPoints += 1
                    feedback.setProgress(int(nPoints * total))
                nIterations += 1

            if nPoints < pointCount:
                QgsMessageLog.logMessage(
                    self.tr('Can not generate requested number of random '
                            'points. Maximum number of attempts exceeded.'),
                    self.tr('Processing'), QgsMessageLog.INFO)

            feedback.setProgress(0)

        del writer
Exemplo n.º 19
0
    def processAlgorithm(self, feedback):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.VECTOR))
        value = float(self.getParameterValue(self.VALUE))
        minDistance = float(self.getParameterValue(self.MIN_DISTANCE))
        strategy = self.getParameterValue(self.STRATEGY)

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QgsWkbTypes.Point, layer.crs())

        da = QgsDistanceArea()

        features = vector.features(layer)
        for current, f in enumerate(features):
            fGeom = f.geometry()
            bbox = fGeom.boundingBox()
            if strategy == 0:
                pointCount = int(value)
            else:
                pointCount = int(round(value * da.measureArea(fGeom)))

            index = QgsSpatialIndex()
            points = dict()

            nPoints = 0
            nIterations = 0
            maxIterations = pointCount * 200
            total = 100.0 / pointCount

            random.seed()

            while nIterations < maxIterations and nPoints < pointCount:
                rx = bbox.xMinimum() + bbox.width() * random.random()
                ry = bbox.yMinimum() + bbox.height() * random.random()

                pnt = QgsPoint(rx, ry)
                geom = QgsGeometry.fromPoint(pnt)
                if geom.within(fGeom) and \
                        vector.checkMinDistance(pnt, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    writer.addFeature(f)
                    index.insertFeature(f)
                    points[nPoints] = pnt
                    nPoints += 1
                    feedback.setProgress(int(nPoints * total))
                nIterations += 1

            if nPoints < pointCount:
                ProcessingLog.addToLog(
                    ProcessingLog.LOG_INFO,
                    self.tr('Can not generate requested number of random '
                            'points. Maximum number of attempts exceeded.'))

            feedback.setProgress(0)

        del writer
Exemplo n.º 20
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.VECTOR))
        groupField = self.getParameterValue(self.GROUP_FIELD)
        orderField = self.getParameterValue(self.ORDER_FIELD)
        dateFormat = unicode(self.getParameterValue(self.DATE_FORMAT))
        #gap = int(self.getParameterValue(self.GAP_PERIOD))
        dirName = self.getOutputValue(self.OUTPUT_TEXT)

        fields = QgsFields()
        fields.append(QgsField('group', QVariant.String, '', 254, 0))
        fields.append(QgsField('begin', QVariant.String, '', 254, 0))
        fields.append(QgsField('end', QVariant.String, '', 254, 0))
        writer = self.getOutputFromName(self.OUTPUT_LINES).getVectorWriter(
            fields, QGis.WKBLineString, layer.crs())

        points = dict()
        features = vector.features(layer)
        total = 100.0 / len(features) if len(features) > 0 else 1
        for current, f in enumerate(features):
            point = f.geometry().asPoint()
            group = f[groupField]
            order = f[orderField]
            if dateFormat != '':
                order = datetime.strptime(unicode(order), dateFormat)
            if group in points:
                points[group].append((order, point))
            else:
                points[group] = [(order, point)]

            progress.setPercentage(int(current * total))

        progress.setPercentage(0)

        da = QgsDistanceArea()

        current = 0
        total = 100.0 / len(points) if len(points) > 0 else 1
        for group, vertices in points.iteritems():
            vertices.sort()
            f = QgsFeature()
            f.initAttributes(len(fields))
            f.setFields(fields)
            f['group'] = group
            f['begin'] = vertices[0][0]
            f['end'] = vertices[-1][0]

            fileName = os.path.join(dirName, '%s.txt' % group)

            fl = open(fileName, 'w')
            fl.write('angle=Azimuth\n')
            fl.write('heading=Coordinate_System\n')
            fl.write('dist_units=Default\n')

            line = []
            i = 0
            for node in vertices:
                line.append(node[1])

                if i == 0:
                    fl.write('startAt=%f;%f;90\n' % (node[1].x(), node[1].y()))
                    fl.write('survey=Polygonal\n')
                    fl.write('[data]\n')
                else:
                    angle = line[i - 1].azimuth(line[i])
                    distance = da.measureLine(line[i - 1], line[i])
                    fl.write('%f;%f;90\n' % (angle, distance))

                i += 1

            f.setGeometry(QgsGeometry.fromPolyline(line))
            writer.addFeature(f)
            current += 1
            progress.setPercentage(int(current * total))

        del writer
        fl.close()
Exemplo n.º 21
0
    def testMeasureLineProjectedWorldPoints(self):
        #   +-+
        #   | |
        # +-+ +
        # checking returned length_mapunits/projected_points of diffferent world points with results from SpatiaLite ST_Project
        da_3068 = QgsDistanceArea()
        da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext())
        if (da_3068.sourceCrs().isGeographic()):
            da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:3068', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description(), da_3068.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_3068.lengthUnits()), da_3068.sourceCrs().projectionAcronym(), da_3068.sourceCrs().ellipsoidAcronym())))
        da_wsg84 = QgsDistanceArea()
        da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext())
        if (da_wsg84.sourceCrs().isGeographic()):
            da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}] ellipsoid[{}]".format(u'EPSG:4326', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_wsg84.lengthUnits()), da_wsg84.sourceCrs().projectionAcronym(), da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.ellipsoid())))
        da_4314 = QgsDistanceArea()
        da_4314.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4314'), QgsProject.instance().transformContext())
        if (da_4314.sourceCrs().isGeographic()):
            da_4314.setEllipsoid(da_4314.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_4314.sourceCrs().authid(), 'EPSG:4314')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:4314', da_4314.sourceCrs().authid(), da_4314.sourceCrs().description(), da_4314.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_4314.lengthUnits()), da_4314.sourceCrs().projectionAcronym(), da_4314.sourceCrs().ellipsoidAcronym())))
        da_4805 = QgsDistanceArea()
        da_4805.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4805'), QgsProject.instance().transformContext())
        if (da_4805.sourceCrs().isGeographic()):
            da_4805.setEllipsoid(da_4805.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_4805.sourceCrs().authid(), 'EPSG:4805')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:4805', da_4805.sourceCrs().authid(), da_4805.sourceCrs().description(), da_4805.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_4805.lengthUnits()), da_4805.sourceCrs().projectionAcronym(), da_4805.sourceCrs().ellipsoidAcronym())))
        # EPSG:5665 unknown, why?
        da_5665 = QgsDistanceArea()
        da_5665.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:5665'), QgsProject.instance().transformContext())
        if (da_5665.sourceCrs().isGeographic()):
            da_5665.setEllipsoid(da_5665.sourceCrs().ellipsoidAcronym())
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:5665', da_5665.sourceCrs().authid(), da_5665.sourceCrs().description(), da_5665.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_5665.lengthUnits()), da_5665.sourceCrs().projectionAcronym(), da_5665.sourceCrs().ellipsoidAcronym())))
        #self.assertEqual(da_5665.sourceCrs().authid(), 'EPSG:5665')
        da_25833 = QgsDistanceArea()
        da_25833.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:25833'), QgsProject.instance().transformContext())
        if (da_25833.sourceCrs().isGeographic()):
            da_25833.setEllipsoid(da_25833.sourceCrs().ellipsoidAcronym())
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}] lengthUnits[{}] projectionAcronym[{}] ellipsoidAcronym[{}]".format(u'EPSG:25833', da_25833.sourceCrs().authid(), da_25833.sourceCrs().description(), da_25833.sourceCrs().isGeographic(), QgsUnitTypes.toString(da_25833.lengthUnits()), da_25833.sourceCrs().projectionAcronym(), da_25833.sourceCrs().ellipsoidAcronym())))
        self.assertEqual(da_25833.sourceCrs().authid(), 'EPSG:25833')

        # Berlin - Brandenburg Gate - Quadriga
        point_berlin_3068 = QgsPointXY(23183.38449999984, 21047.3225000017)
        point_berlin_3068_project = point_berlin_3068.project(1, (math.pi / 2))
        point_meter_result = QgsPointXY(0, 0)
        length_meter_mapunits, point_meter_result = da_3068.measureLineProjected(point_berlin_3068, 1.0, (math.pi / 2))
        pprint(point_meter_result)
        print('-I-> Berlin 3068 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_3068.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 1, da_3068.lengthUnits(), True), '1.0 m')
        self.assertEqual(point_meter_result.toString(7), point_berlin_3068_project.toString(7))
        point_berlin_wsg84 = QgsPointXY(13.37770458660236, 52.51627178856762)
        point_berlin_wsg84_project = QgsPointXY(13.37771931736259, 52.51627178856669)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_berlin_wsg84, 1.0, (math.pi / 2))
        print('-I-> Berlin Wsg84 length_meter_mapunits[{}] point_meter_result[{}] ellipsoid[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 20, da_wsg84.lengthUnits(), True), point_meter_result.asWkt(), da_wsg84.ellipsoid()))
        # for unknown reasons, this is returning '0.00001473026 m' instead of '0.00001473026 deg' when using da_wsg84.lengthUnits()
        # self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits,11,da_wsg84.lengthUnits(),True), '0.00001473026 deg')
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 11, QgsUnitTypes.DistanceDegrees, True), '0.00001473026 deg')
        self.assertEqual(point_meter_result.toString(7), point_berlin_wsg84_project.toString(7))
        point_berlin_4314 = QgsPointXY(13.37944343021465, 52.51767872437083)
        point_berlin_4314_project = QgsPointXY(13.37945816324759, 52.5176787243699)
        length_meter_mapunits, point_meter_result = da_4314.measureLineProjected(point_berlin_4314, 1.0, (math.pi / 2))
        print('-I-> Berlin 4314 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_4314.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 9, QgsUnitTypes.DistanceDegrees, True), '0.000014733 deg')
        self.assertEqual(point_meter_result.toString(7), point_berlin_4314_project.toString(7))
        point_berlin_4805 = QgsPointXY(31.04960570069176, 52.5174657497405)
        point_berlin_4805_project = QgsPointXY(31.04962043365347, 52.51746574973957)
        length_meter_mapunits, point_meter_result = da_4805.measureLineProjected(point_berlin_4805, 1.0, (math.pi / 2))
        print('-I-> Berlin 4805 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_4805.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 9, QgsUnitTypes.DistanceDegrees, True), '0.000014733 deg')
        self.assertEqual(point_meter_result.toString(7), point_berlin_4805_project.toString(7))
        point_berlin_25833 = QgsPointXY(389918.0748318382, 5819698.772194743)
        point_berlin_25833_project = point_berlin_25833.project(1, (math.pi / 2))
        length_meter_mapunits, point_meter_result = da_25833.measureLineProjected(point_berlin_25833, 1.0, (math.pi / 2))
        print('-I-> Berlin 25833 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_25833.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_25833.lengthUnits(), True), '1.0000000 m')
        self.assertEqual(point_meter_result.toString(7), point_berlin_25833_project.toString(7))
        if da_5665.sourceCrs().authid() != "":
            point_berlin_5665 = QgsPointXY(3389996.871728864, 5822169.719727578)
            point_berlin_5665_project = point_berlin_5665.project(1, (math.pi / 2))
            length_meter_mapunits, point_meter_result = da_5665.measureLineProjected(point_berlin_5665, 1.0, (math.pi / 2))
            print('-I-> Berlin 5665 length_meter_mapunits[{}] point_meter_result[{}]'.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_5665.lengthUnits(), True), point_meter_result.asWkt()))
            self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 1.0, da_5665.lengthUnits(), True), '1.0 m')
            self.assertEqual(point_meter_result.toString(7), point_berlin_5665_project.toString(7))
        print('\n12 points ''above over'' and on the Equator')
        point_wsg84 = QgsPointXY(25.7844, 71.1725)
        point_wsg84_project = QgsPointXY(25.78442775215388, 71.17249999999795)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Nordkap, Norway - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000278 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(24.95995, 60.16841)
        point_wsg84_project = QgsPointXY(24.95996801277454, 60.16840999999877)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Helsinki, Finnland - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001801 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(12.599278, 55.692861)
        point_wsg84_project = QgsPointXY(12.59929390161872, 55.69286099999897)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Copenhagen, Denmark - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001590 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))

        point_wsg84 = QgsPointXY(-0.001389, 51.477778)
        point_wsg84_project = QgsPointXY(-0.001374606184398, 51.4777779999991)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Royal Greenwich Observatory, United Kingdom - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001439 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(7.58769, 47.55814)
        point_wsg84_project = QgsPointXY(7.587703287209086, 47.55813999999922)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Basel, Switzerland - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001329 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(11.255278, 43.775278)
        point_wsg84_project = QgsPointXY(11.25529042107924, 43.77527799999933)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Florenz, Italy - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001242 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(14.514722, 35.899722)
        point_wsg84_project = QgsPointXY(14.51473307693308, 35.89972199999949)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Valletta, Malta - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001108 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-79.933333, 32.783333)
        point_wsg84_project = QgsPointXY(-79.93332232547254, 32.78333299999955)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Charlston, South Carolina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001067 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-17.6666666, 27.733333)
        point_wsg84_project = QgsPointXY(-17.66665645831515, 27.73333299999962)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Ferro, Spain - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001014 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-99.133333, 19.433333)
        point_wsg84_project = QgsPointXY(-99.1333234776827, 19.43333299999975)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Mexico City, Mexico - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000952 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-79.894444, 9.341667)
        point_wsg84_project = QgsPointXY(-79.89443489691369, 9.341666999999882)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Colón, Panama - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000910 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-74.075833, 4.598056)
        point_wsg84_project = QgsPointXY(-74.07582398803629, 4.598055999999943)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Bogotá, Colombia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000901 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(0, 0)
        point_wsg84_project = QgsPointXY(0.000008983152841, 0)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Equator, Atlantic Ocean - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000898 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        print('\n12 points ''down under'' and 1 point that should be considered invalid')
        point_wsg84 = QgsPointXY(-78.509722, -0.218611)
        point_wsg84_project = QgsPointXY(-78.50971301678221, -0.218610999999997)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Quito, Ecuador - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000898 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(106.816667, -6.2)
        point_wsg84_project = QgsPointXY(106.8166760356519, -6.199999999999922)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Jakarta, Indonesia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000904 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-77.018611, -12.035)
        point_wsg84_project = QgsPointXY(-77.01860181630058, -12.03499999999985)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Lima, Peru - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000918 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(25.466667, -10.716667)
        point_wsg84_project = QgsPointXY(25.46667614155322, -10.71666699999986)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Kolwezi, Congo - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000914 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-70.333333, -18.483333)
        point_wsg84_project = QgsPointXY(-70.3333235314429, -18.48333299999976)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Arica, Chile - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00000947 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-70.666667, -33.45)
        point_wsg84_project = QgsPointXY(-70.66665624452817, -33.44999999999953)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Santiago, Chile - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001076 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(144.9604, -37.8191)
        point_wsg84_project = QgsPointXY(144.96041135746983741, -37.81909999999945171)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Melbourne, Australia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001136 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(147.29, -42.88)
        point_wsg84_project = QgsPointXY(147.2900122399815, -42.87999999999934)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Hobart City,Tasmania, Australia - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001224 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(168.101667, -46.899722)
        point_wsg84_project = QgsPointXY(168.101680123673, -46.89972199999923)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Ryan''s Creek Aerodrome, New Zealand - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001312 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-69.216667, -51.633333)
        point_wsg84_project = QgsPointXY(-69.21665255700216, -51.6333329999991)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Río Gallegos, Argentina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001444 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-68.3, -54.8)
        point_wsg84_project = QgsPointXY(-68.29998445081456, -54.79999999999899)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Ushuaia, Tierra del Fuego, Argentina - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00001555 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-63.494444, -64.825278)
        point_wsg84_project = QgsPointXY(-63.49442294002932, -64.82527799999851)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Port Lockroy, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00002106 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-180, -84.863272250)
        point_wsg84_project = QgsPointXY(-179.9999000000025, -84.8632722499922)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-I-> Someware, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00010000 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
        point_wsg84 = QgsPointXY(-180, -85.0511300)
        point_wsg84_project = QgsPointXY(-179.9998962142197, -85.05112999999191)
        length_meter_mapunits, point_meter_result = da_wsg84.measureLineProjected(point_wsg84, 1.0, (math.pi / 2))
        print('-W-> Mercator''s Last Stop, Antarctica - Wsg84 - length_meter_mapunits[{}] point_meter_result[{}] '.format(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, da_wsg84.lengthUnits(), True), point_meter_result.asWkt()))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 8, QgsUnitTypes.DistanceDegrees, True), '0.00010379 deg')
        self.assertEqual(point_meter_result.toString(7), point_wsg84_project.toString(7))
Exemplo n.º 22
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.VECTOR))
        pointCount = float(self.getParameterValue(self.POINT_NUMBER))
        minDistance = float(self.getParameterValue(self.MIN_DISTANCE))

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QGis.WKBPoint,
            layer.dataProvider().crs())

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        featureCount = layer.featureCount()
        total = 100.0 / pointCount

        index = QgsSpatialIndex()
        points = dict()

        da = QgsDistanceArea()
        request = QgsFeatureRequest()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            # pick random feature
            fid = random.randint(0, featureCount - 1)
            f = layer.getFeatures(request.setFilterFid(fid)).next()
            fGeom = QgsGeometry(f.geometry())

            if fGeom.isMultipart():
                lines = fGeom.asMultiPolyline()
                # pick random line
                lineId = random.randint(0, len(lines) - 1)
                vertices = lines[lineId]
            else:
                vertices = fGeom.asPolyline()

            # pick random segment
            if len(vertices) == 2:
                vid = 0
            else:
                vid = random.randint(0, len(vertices) - 2)
            startPoint = vertices[vid]
            endPoint = vertices[vid + 1]
            length = da.measureLine(startPoint, endPoint)
            dist = length * random.random()

            if dist > minDistance:
                d = dist / (length - dist)
                rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
                ry = (startPoint.y() + d * endPoint.y()) / (1 + d)

                # generate random point
                pnt = QgsPoint(rx, ry)
                geom = QgsGeometry.fromPoint(pnt)
                if vector.checkMinDistance(pnt, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    writer.addFeature(f)
                    index.insertFeature(f)
                    points[nPoints] = pnt
                    nPoints += 1
                    progress.setPercentage(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            ProcessingLog.addToLog(
                ProcessingLog.LOG_INFO,
                self.tr('Can not generate requested number of random points. '
                        'Maximum number of attempts exceeded.'))

        del writer
Exemplo n.º 23
0
    def testMeasureLineProjected(self):
        #   +-+
        #   | |
        # +-+ +
        # test setting/getting the source CRS
        da_3068 = QgsDistanceArea()
        da_wsg84 = QgsDistanceArea()

        da_3068.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:3068'), QgsProject.instance().transformContext())
        if (da_3068.sourceCrs().isGeographic()):
            da_3068.setEllipsoid(da_3068.sourceCrs().ellipsoidAcronym())
        print(("setting [{}] srid [{}] description [{}]".format(u'Soldner Berlin', da_3068.sourceCrs().authid(), da_3068.sourceCrs().description())))
        self.assertEqual(da_3068.sourceCrs().authid(), 'EPSG:3068')
        da_wsg84.setSourceCrs(QgsCoordinateReferenceSystem.fromOgcWmsCrs('EPSG:4326'), QgsProject.instance().transformContext())
        if (da_wsg84.sourceCrs().isGeographic()):
            da_wsg84.setEllipsoid(da_wsg84.sourceCrs().ellipsoidAcronym())
        self.assertEqual(da_wsg84.sourceCrs().authid(), 'EPSG:4326')
        print(("setting [{}] srid [{}] description [{}] isGeographic[{}]".format(u'Wsg84', da_wsg84.sourceCrs().authid(), da_wsg84.sourceCrs().description(), da_wsg84.sourceCrs().isGeographic())))
        # print(("-- projectionAcronym[{}] ellipsoidAcronym[{}] toWkt[{}] mapUnits[{}] toProj4[{}]".format(da_wsg84.sourceCrs().projectionAcronym(),da_wsg84.sourceCrs().ellipsoidAcronym(), da_wsg84.sourceCrs().toWkt(),da_wsg84.sourceCrs().mapUnits(),da_wsg84.sourceCrs().toProj4())))
        print(("Testing Position change for[{}] years[{}]".format(u'Ampelanlage - Potsdamer Platz, Verkehrsinsel', u'1924 and 1998')))

        # 1924-10-24 SRID=3068;POINT(23099.49 20296.69)
        # 1924-10-24 SRID=4326;POINT(13.37650707988041 52.50952361017194)
        # 1998-10-02 SRID=3068;POINT(23082.30 20267.80)
        # 1998-10-02 SRID=4326;POINT(13.37625537334001 52.50926345498337)
        # values returned by SpatiaLite
        point_soldner_1924 = QgsPointXY(23099.49, 20296.69)
        point_soldner_1998 = QgsPointXY(23082.30, 20267.80)
        distance_soldner_meters = 33.617379
        azimuth_soldner_1924 = 3.678339
        # ST_Transform(point_soldner_1924,point_soldner_1998,4326)
        point_wsg84_1924 = QgsPointXY(13.37650707988041, 52.50952361017194)
        point_wsg84_1998 = QgsPointXY(13.37625537334001, 52.50926345498337)
        # ST_Distance(point_wsg84_1924,point_wsg84_1998,1)
        distance_wsg84_meters = 33.617302
        # ST_Distance(point_wsg84_1924,point_wsg84_1998)
        # distance_wsg84_mapunits=0.000362
        distance_wsg84_mapunits_format = QgsDistanceArea.formatDistance(0.000362, 7, QgsUnitTypes.DistanceDegrees, True)
        # ST_Azimuth(point_wsg84_1924,point_wsg84_1998)
        azimuth_wsg84_1924 = 3.674878
        # ST_Azimuth(point_wsg84_1998,point_wsg84_1998)
        azimuth_wsg84_1998 = 0.533282
        # ST_Project(point_wsg84_1924,33.617302,3.674878)
        # SRID=4326;POINT(13.37625537318728 52.50926345503591)
        point_soldner_1998_project = QgsPointXY(13.37625537318728, 52.50926345503591)
        # ST_Project(point_wsg84_1998,33.617302,0.533282)
        # SRID=4326;POINT(13.37650708009255 52.50952361009799)
        point_soldner_1924_project = QgsPointXY(13.37650708009255, 52.50952361009799)

        distance_qpoint = point_soldner_1924.distance(point_soldner_1998)
        azimuth_qpoint = point_soldner_1924.azimuth(point_soldner_1998)
        point_soldner_1998_result = point_soldner_1924.project(distance_qpoint, azimuth_qpoint)

        point_soldner_1924_result = QgsPointXY(0, 0)
        point_soldner_1998_result = QgsPointXY(0, 0)
        # Test meter based projected point from point_1924 to point_1998
        length_1998_mapunits, point_soldner_1998_result = da_3068.measureLineProjected(point_soldner_1924, distance_soldner_meters, azimuth_qpoint)
        self.assertEqual(point_soldner_1998_result.toString(6), point_soldner_1998.toString(6))
        # Test degree based projected point from point_1924 1 meter due East
        point_wsg84_meter_result = QgsPointXY(0, 0)
        point_wsg84_1927_meter = QgsPointXY(13.37652180838435, 52.50952361017102)
        length_meter_mapunits, point_wsg84_meter_result = da_wsg84.measureLineProjected(point_wsg84_1924, 1.0, (math.pi / 2))
        self.assertEqual(QgsDistanceArea.formatDistance(length_meter_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), '0.0000147 deg')
        self.assertEqual(point_wsg84_meter_result.toString(7), point_wsg84_1927_meter.toString(7))

        point_wsg84_1998_result = QgsPointXY(0, 0)
        length_1928_mapunits, point_wsg84_1998_result = da_wsg84.measureLineProjected(point_wsg84_1924, distance_wsg84_meters, azimuth_wsg84_1924)
        self.assertEqual(QgsDistanceArea.formatDistance(length_1928_mapunits, 7, QgsUnitTypes.DistanceDegrees, True), distance_wsg84_mapunits_format)
        self.assertEqual(point_wsg84_1998_result.toString(7), point_wsg84_1998.toString(7))
Exemplo n.º 24
0
    def testLengthMeasureAndUnits(self):
        """Test a variety of length measurements in different CRS and ellipsoid modes, to check that the
           calculated lengths and units are always consistent
        """

        da = QgsDistanceArea()
        da.setSourceCrs(3452)
        da.setEllipsoidalMode(False)
        da.setEllipsoid("NONE")
        daCRS = QgsCoordinateReferenceSystem()
        daCRS = da.sourceCrs()

        # We check both the measured length AND the units, in case the logic regarding
        # ellipsoids and units changes in future
        distance = da.measureLine(QgsPoint(1, 1), QgsPoint(2, 3))
        units = da.lengthUnits()

        print(("measured {} in {}".format(distance,
                                          QgsUnitTypes.toString(units))))
        assert ((abs(distance - 2.23606797) < 0.00000001
                 and units == QgsUnitTypes.DistanceDegrees)
                or (abs(distance - 248.52) < 0.01
                    and units == QgsUnitTypes.DistanceMeters))

        da.setEllipsoid("WGS84")
        distance = da.measureLine(QgsPoint(1, 1), QgsPoint(2, 3))
        units = da.lengthUnits()

        print(("measured {} in {}".format(distance,
                                          QgsUnitTypes.toString(units))))
        assert ((abs(distance - 2.23606797) < 0.00000001
                 and units == QgsUnitTypes.DistanceDegrees)
                or (abs(distance - 248.52) < 0.01
                    and units == QgsUnitTypes.DistanceMeters))

        da.setEllipsoidalMode(True)
        distance = da.measureLine(QgsPoint(1, 1), QgsPoint(2, 3))
        units = da.lengthUnits()

        print(("measured {} in {}".format(distance,
                                          QgsUnitTypes.toString(units))))
        # should always be in Meters
        self.assertAlmostEqual(distance, 247555.57, delta=0.01)
        self.assertEqual(units, QgsUnitTypes.DistanceMeters)

        # test converting the resultant length
        distance = da.convertLengthMeasurement(
            distance, QgsUnitTypes.DistanceNauticalMiles)
        self.assertAlmostEqual(distance, 133.669, delta=0.01)

        # now try with a source CRS which is in feet
        da.setSourceCrs(27469)
        da.setEllipsoidalMode(False)
        # measurement should be in feet
        distance = da.measureLine(QgsPoint(1, 1), QgsPoint(2, 3))
        units = da.lengthUnits()
        print(("measured {} in {}".format(distance,
                                          QgsUnitTypes.toString(units))))
        self.assertAlmostEqual(distance, 2.23606797, delta=0.000001)
        self.assertEqual(units, QgsUnitTypes.DistanceFeet)

        # test converting the resultant length
        distance = da.convertLengthMeasurement(distance,
                                               QgsUnitTypes.DistanceMeters)
        self.assertAlmostEqual(distance, 0.6815, delta=0.001)

        da.setEllipsoidalMode(True)
        # now should be in Meters again
        distance = da.measureLine(QgsPoint(1, 1), QgsPoint(2, 3))
        units = da.lengthUnits()
        print(("measured {} in {}".format(distance,
                                          QgsUnitTypes.toString(units))))
        self.assertAlmostEqual(distance, 0.67953772, delta=0.000001)
        self.assertEqual(units, QgsUnitTypes.DistanceMeters)

        # test converting the resultant length
        distance = da.convertLengthMeasurement(distance,
                                               QgsUnitTypes.DistanceFeet)
        self.assertAlmostEqual(distance, 2.2294, delta=0.001)
Exemplo n.º 25
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        method = self.parameterAsEnum(parameters, self.METHOD, context)

        wkb_type = source.wkbType()
        fields = source.fields()

        new_fields = QgsFields()
        if QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.PolygonGeometry:
            new_fields.append(QgsField('area', QVariant.Double))
            new_fields.append(QgsField('perimeter', QVariant.Double))
        elif QgsWkbTypes.geometryType(wkb_type) == QgsWkbTypes.LineGeometry:
            new_fields.append(QgsField('length', QVariant.Double))
            if not QgsWkbTypes.isMultiType(source.wkbType()):
                new_fields.append(QgsField('straightdis', QVariant.Double))
                new_fields.append(QgsField('sinuosity', QVariant.Double))
        else:
            new_fields.append(QgsField('xcoord', QVariant.Double))
            new_fields.append(QgsField('ycoord', QVariant.Double))
            if QgsWkbTypes.hasZ(source.wkbType()):
                self.export_z = True
                new_fields.append(QgsField('zcoord', QVariant.Double))
            if QgsWkbTypes.hasM(source.wkbType()):
                self.export_m = True
                new_fields.append(QgsField('mvalue', QVariant.Double))

        fields = QgsProcessingUtils.combineFields(fields, new_fields)
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, fields, wkb_type,
                                               source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        coordTransform = None

        # Calculate with:
        # 0 - layer CRS
        # 1 - project CRS
        # 2 - ellipsoidal

        self.distance_area = QgsDistanceArea()
        if method == 2:
            self.distance_area.setSourceCrs(source.sourceCrs(),
                                            context.transformContext())
            self.distance_area.setEllipsoid(context.project().ellipsoid())
        elif method == 1:
            coordTransform = QgsCoordinateTransform(source.sourceCrs(),
                                                    context.project().crs(),
                                                    context.project())

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

            outFeat = f
            attrs = f.attributes()
            inGeom = f.geometry()
            if inGeom:
                if coordTransform is not None:
                    inGeom.transform(coordTransform)

                if inGeom.type() == QgsWkbTypes.PointGeometry:
                    attrs.extend(self.point_attributes(inGeom))
                elif inGeom.type() == QgsWkbTypes.PolygonGeometry:
                    attrs.extend(self.polygon_attributes(inGeom))
                else:
                    attrs.extend(self.line_attributes(inGeom))

            # ensure consistent count of attributes - otherwise null
            # geometry features will have incorrect attribute length
            # and provider may reject them
            if len(attrs) < len(fields):
                attrs += [NULL] * (len(fields) - len(attrs))

            outFeat.setAttributes(attrs)
            sink.addFeature(outFeat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 26
0
    def processAlgorithm(self, context, feedback):
        lineLayer = dataobjects.getLayerFromString(
            self.getParameterValue(self.LINES))
        polyLayer = dataobjects.getLayerFromString(
            self.getParameterValue(self.POLYGONS))
        lengthFieldName = self.getParameterValue(self.LEN_FIELD)
        countFieldName = self.getParameterValue(self.COUNT_FIELD)

        (idxLength,
         fieldList) = vector.findOrCreateField(polyLayer, polyLayer.fields(),
                                               lengthFieldName)
        (idxCount,
         fieldList) = vector.findOrCreateField(polyLayer, fieldList,
                                               countFieldName)

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fieldList.toList(), polyLayer.wkbType(), polyLayer.crs(), context)

        spatialIndex = vector.spatialindex(lineLayer)

        ftLine = QgsFeature()
        ftPoly = QgsFeature()
        outFeat = QgsFeature()
        inGeom = QgsGeometry()
        outGeom = QgsGeometry()
        distArea = QgsDistanceArea()

        features = QgsProcessingUtils.getFeatures(polyLayer, context)
        total = 100.0 / QgsProcessingUtils.featureCount(polyLayer, context)
        hasIntersections = False
        for current, ftPoly in enumerate(features):
            inGeom = ftPoly.geometry()
            attrs = ftPoly.attributes()
            count = 0
            length = 0
            hasIntersections = False
            lines = spatialIndex.intersects(inGeom.boundingBox())
            engine = None
            if len(lines) > 0:
                hasIntersections = True
                # use prepared geometries for faster intersection tests
                engine = QgsGeometry.createGeometryEngine(inGeom.geometry())
                engine.prepareGeometry()

            if hasIntersections:
                request = QgsFeatureRequest().setFilterFids(
                    lines).setSubsetOfAttributes([])
                for ftLine in lineLayer.getFeatures(request):
                    tmpGeom = ftLine.geometry()
                    if engine.intersects(tmpGeom.geometry()):
                        outGeom = inGeom.intersection(tmpGeom)
                        length += distArea.measureLength(outGeom)
                        count += 1

            outFeat.setGeometry(inGeom)
            if idxLength == len(attrs):
                attrs.append(length)
            else:
                attrs[idxLength] = length
            if idxCount == len(attrs):
                attrs.append(count)
            else:
                attrs[idxCount] = count
            outFeat.setAttributes(attrs)
            writer.addFeature(outFeat)

            feedback.setProgress(int(current * total))

        del writer
Exemplo n.º 27
0
    def linearMatrix(self, parameters, context, source, inField, target_source, targetField, same_source_and_target,
                     matType, nPoints, feedback):

        if same_source_and_target:
            # need to fetch an extra point from the index, since the closest match will always be the same
            # as the input feature
            nPoints += 1

        inIdx = source.fields().lookupField(inField)
        outIdx = target_source.fields().lookupField(targetField)

        fields = QgsFields()
        input_id_field = source.fields()[inIdx]
        input_id_field.setName('InputID')
        fields.append(input_id_field)
        if matType == 0:
            target_id_field = target_source.fields()[outIdx]
            target_id_field.setName('TargetID')
            fields.append(target_id_field)
            fields.append(QgsField('Distance', QVariant.Double))
        else:
            fields.append(QgsField('MEAN', QVariant.Double))
            fields.append(QgsField('STDDEV', QVariant.Double))
            fields.append(QgsField('MIN', QVariant.Double))
            fields.append(QgsField('MAX', QVariant.Double))

        out_wkb = QgsWkbTypes.multiType(source.wkbType()) if matType == 0 else source.wkbType()
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               fields, out_wkb, source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        index = QgsSpatialIndex(target_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]).setDestinationCrs(source.sourceCrs(), context.transformContext())), feedback)

        distArea = QgsDistanceArea()
        distArea.setSourceCrs(source.sourceCrs(), context.transformContext())
        distArea.setEllipsoid(context.project().ellipsoid())

        features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([inIdx]))
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        for current, inFeat in enumerate(features):
            if feedback.isCanceled():
                break

            inGeom = inFeat.geometry()
            inID = str(inFeat.attributes()[inIdx])
            featList = index.nearestNeighbor(inGeom.asPoint(), nPoints)
            distList = []
            vari = 0.0
            request = QgsFeatureRequest().setFilterFids(featList).setSubsetOfAttributes([outIdx]).setDestinationCrs(source.sourceCrs(), context.transformContext())
            for outFeat in target_source.getFeatures(request):
                if feedback.isCanceled():
                    break

                if same_source_and_target and inFeat.id() == outFeat.id():
                    continue

                outID = outFeat.attributes()[outIdx]
                outGeom = outFeat.geometry()
                dist = distArea.measureLine(inGeom.asPoint(),
                                            outGeom.asPoint())

                if matType == 0:
                    out_feature = QgsFeature()
                    out_geom = QgsGeometry.unaryUnion([inFeat.geometry(), outFeat.geometry()])
                    out_feature.setGeometry(out_geom)
                    out_feature.setAttributes([inID, outID, dist])
                    sink.addFeature(out_feature, QgsFeatureSink.FastInsert)
                else:
                    distList.append(float(dist))

            if matType != 0:
                mean = sum(distList) / len(distList)
                for i in distList:
                    vari += (i - mean) * (i - mean)
                vari = math.sqrt(vari / len(distList))

                out_feature = QgsFeature()
                out_feature.setGeometry(inFeat.geometry())
                out_feature.setAttributes([inID, mean, vari, min(distList), max(distList)])
                sink.addFeature(out_feature, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 28
0
    def processAlgorithm(self, parameters, context, feedback):
        line_source = self.parameterAsSource(parameters, self.LINES, context)
        if line_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.LINES))

        poly_source = self.parameterAsSource(parameters, self.POLYGONS,
                                             context)
        if poly_source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.POLYGONS))

        length_field_name = self.parameterAsString(parameters, self.LEN_FIELD,
                                                   context)
        count_field_name = self.parameterAsString(parameters, self.COUNT_FIELD,
                                                  context)

        fields = poly_source.fields()
        if fields.lookupField(length_field_name) < 0:
            fields.append(QgsField(length_field_name, QVariant.Double))
        length_field_index = fields.lookupField(length_field_name)
        if fields.lookupField(count_field_name) < 0:
            fields.append(QgsField(count_field_name, QVariant.Int))
        count_field_index = fields.lookupField(count_field_name)

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

        spatialIndex = QgsSpatialIndex(
            line_source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(
                []).setDestinationCrs(poly_source.sourceCrs(),
                                      context.transformContext())), feedback)

        distArea = QgsDistanceArea()
        distArea.setSourceCrs(poly_source.sourceCrs(),
                              context.transformContext())
        distArea.setEllipsoid(context.project().ellipsoid())

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

            output_feature = QgsFeature()
            count = 0
            length = 0
            if poly_feature.hasGeometry():
                poly_geom = poly_feature.geometry()
                has_intersections = False
                lines = spatialIndex.intersects(poly_geom.boundingBox())
                engine = None
                if len(lines) > 0:
                    has_intersections = True
                    # use prepared geometries for faster intersection tests
                    engine = QgsGeometry.createGeometryEngine(
                        poly_geom.constGet())
                    engine.prepareGeometry()

                if has_intersections:
                    request = QgsFeatureRequest().setFilterFids(
                        lines).setSubsetOfAttributes([]).setDestinationCrs(
                            poly_source.sourceCrs(),
                            context.transformContext())
                    for line_feature in line_source.getFeatures(request):
                        if feedback.isCanceled():
                            break

                        if engine.intersects(
                                line_feature.geometry().constGet()):
                            outGeom = poly_geom.intersection(
                                line_feature.geometry())
                            length += distArea.measureLength(outGeom)
                            count += 1

                output_feature.setGeometry(poly_geom)

            attrs = poly_feature.attributes()
            if length_field_index == len(attrs):
                attrs.append(length)
            else:
                attrs[length_field_index] = length
            if count_field_index == len(attrs):
                attrs.append(count)
            else:
                attrs[count_field_index] = count
            output_feature.setAttributes(attrs)
            sink.addFeature(output_feature, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Exemplo n.º 29
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.INPUT, context)
        if source is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT))

        strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
        minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE,
                                             context)

        expression = QgsExpression(
            self.parameterAsString(parameters, self.EXPRESSION, context))
        if expression.hasParserError():
            raise QgsProcessingException(expression.parserErrorString())

        expressionContext = self.createExpressionContext(
            parameters, context, source)
        expression.prepare(expressionContext)

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

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

        da = QgsDistanceArea()
        da.setSourceCrs(source.sourceCrs(), context.transformContext())
        da.setEllipsoid(context.project().ellipsoid())

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

            if not f.hasGeometry():
                continue

            current_progress = total * current
            feedback.setProgress(current_progress)

            expressionContext.setFeature(f)
            value = expression.evaluate(expressionContext)
            if expression.hasEvalError():
                feedback.pushInfo(
                    self.tr('Evaluation error for feature ID {}: {}').format(
                        f.id(), expression.evalErrorString()))
                continue

            fGeom = f.geometry()
            engine = QgsGeometry.createGeometryEngine(fGeom.constGet())
            engine.prepareGeometry()

            bbox = fGeom.boundingBox()
            if strategy == 0:
                pointCount = int(value)
            else:
                pointCount = int(round(value * da.measureArea(fGeom)))

            if pointCount == 0:
                feedback.pushInfo(
                    "Skip feature {} as number of points for it is 0.".format(
                        f.id()))
                continue

            index = QgsSpatialIndex()
            points = dict()

            nPoints = 0
            nIterations = 0
            maxIterations = pointCount * 200
            feature_total = total / pointCount if pointCount else 1

            random.seed()

            while nIterations < maxIterations and nPoints < pointCount:
                if feedback.isCanceled():
                    break

                rx = bbox.xMinimum() + bbox.width() * random.random()
                ry = bbox.yMinimum() + bbox.height() * random.random()

                p = QgsPointXY(rx, ry)
                geom = QgsGeometry.fromPointXY(p)
                if engine.contains(geom.constGet()) and \
                        vector.checkMinDistance(p, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    sink.addFeature(f, QgsFeatureSink.FastInsert)
                    index.insertFeature(f)
                    points[nPoints] = p
                    nPoints += 1
                    feedback.setProgress(current_progress +
                                         int(nPoints * feature_total))
                nIterations += 1

            if nPoints < pointCount:
                feedback.pushInfo(
                    self.tr('Could not generate requested number of random '
                            'points. Maximum number of attempts exceeded.'))

        feedback.setProgress(100)

        return {self.OUTPUT: dest_id}
Exemplo n.º 30
0
    def drawScaleBar(self, theComposerMap, theTopOffset):
        """Add a numeric scale to the bottom left of the map

        We draw the scale bar manually because QGIS does not yet support
        rendering a scalebar for a geographic map in km.

        .. seealso:: :meth:`drawNativeScaleBar`

        Args:
            * theComposerMap - QgsComposerMap instance used as the basis
              scale calculations.
            * theTopOffset - vertical offset at which the map should be drawn
        Returns:
            None
        Raises:
            Any exceptions raised by the InaSAFE library will be propagated.
        """
        LOGGER.debug('InaSAFE Map drawScaleBar called')
        myCanvas = self.iface.mapCanvas()
        myRenderer = myCanvas.mapRenderer()
        #
        # Add a linear map scale
        #
        myDistanceArea = QgsDistanceArea()
        myDistanceArea.setSourceCrs(myRenderer.destinationCrs().srsid())
        myDistanceArea.setProjectionsEnabled(True)
        # Determine how wide our map is in km/m
        # Starting point at BL corner
        myComposerExtent = theComposerMap.extent()
        myStartPoint = QgsPoint(myComposerExtent.xMinimum(),
                                myComposerExtent.yMinimum())
        # Ending point at BR corner
        myEndPoint = QgsPoint(myComposerExtent.xMaximum(),
                              myComposerExtent.yMinimum())
        myGroundDistance = myDistanceArea.measureLine(myStartPoint, myEndPoint)
        # Get the equivalent map distance per page mm
        myMapWidth = self.mapWidth
        # How far is 1mm on map on the ground in meters?
        myMMToGroundDistance = myGroundDistance / myMapWidth
        #print 'MM:', myMMDistance
        # How long we want the scale bar to be in relation to the map
        myScaleBarToMapRatio = 0.5
        # How many divisions the scale bar should have
        myTickCount = 5
        myScaleBarWidthMM = myMapWidth * myScaleBarToMapRatio
        myPrintSegmentWidthMM = myScaleBarWidthMM / myTickCount
        # Segment width in real world (m)
        # We apply some logic here so that segments are displayed in meters
        # if each segment is less that 1000m otherwise km. Also the segment
        # lengths are rounded down to human looking numbers e.g. 1km not 1.1km
        myUnits = ''
        myGroundSegmentWidth = myPrintSegmentWidthMM * myMMToGroundDistance
        if myGroundSegmentWidth < 1000:
            myUnits = 'm'
            myGroundSegmentWidth = round(myGroundSegmentWidth)
            # adjust the segment width now to account for rounding
            myPrintSegmentWidthMM = myGroundSegmentWidth / myMMToGroundDistance
        else:
            myUnits = 'km'
            # Segment with in real world (km)
            myGroundSegmentWidth = round(myGroundSegmentWidth / 1000)
            myPrintSegmentWidthMM = ((myGroundSegmentWidth * 1000) /
                                     myMMToGroundDistance)
        # Now adjust the scalebar width to account for rounding
        myScaleBarWidthMM = myTickCount * myPrintSegmentWidthMM

        #print "SBWMM:", myScaleBarWidthMM
        #print "SWMM:", myPrintSegmentWidthMM
        #print "SWM:", myGroundSegmentWidthM
        #print "SWKM:", myGroundSegmentWidthKM
        # start drawing in line segments
        myScaleBarHeight = 5  # mm
        myLineWidth = 0.3  # mm
        myInsetDistance = 7  # how much to inset the scalebar into the map by
        myScaleBarX = self.pageMargin + myInsetDistance
        myScaleBarY = (theTopOffset + self.mapHeight - myInsetDistance -
                       myScaleBarHeight)  # mm

        # Draw an outer background box - shamelessly hardcoded buffer
        myRect = QgsComposerShape(
            myScaleBarX - 4,  # left edge
            myScaleBarY - 3,  # top edge
            myScaleBarWidthMM + 13,  # right edge
            myScaleBarHeight + 6,  # bottom edge
            self.composition)

        myRect.setShapeType(QgsComposerShape.Rectangle)
        myRect.setLineWidth(myLineWidth)
        myRect.setFrame(False)
        myBrush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        # workaround for missing setTransparentFill missing from python api
        myRect.setBrush(myBrush)
        self.composition.addItem(myRect)
        # Set up the tick label font
        myFontWeight = QtGui.QFont.Normal
        myFontSize = 6
        myItalicsFlag = False
        myFont = QtGui.QFont('verdana', myFontSize, myFontWeight,
                             myItalicsFlag)
        # Draw the bottom line
        myUpshift = 0.3  # shift the bottom line up for better rendering
        myRect = QgsComposerShape(myScaleBarX,
                                  myScaleBarY + myScaleBarHeight - myUpshift,
                                  myScaleBarWidthMM, 0.1, self.composition)

        myRect.setShapeType(QgsComposerShape.Rectangle)
        myRect.setLineWidth(myLineWidth)
        myRect.setFrame(False)
        self.composition.addItem(myRect)

        # Now draw the scalebar ticks
        for myTickCountIterator in range(0, myTickCount + 1):
            myDistanceSuffix = ''
            if myTickCountIterator == myTickCount:
                myDistanceSuffix = ' ' + myUnits
            myRealWorldDistance = (
                '%.0f%s' %
                (myTickCountIterator * myGroundSegmentWidth, myDistanceSuffix))
            #print 'RW:', myRealWorldDistance
            myMMOffset = myScaleBarX + (myTickCountIterator *
                                        myPrintSegmentWidthMM)
            #print 'MM:', myMMOffset
            myTickHeight = myScaleBarHeight / 2
            # Lines are not exposed by the api yet so we
            # bodge drawing lines using rectangles with 1px height or width
            myTickWidth = 0.1  # width or rectangle to be drawn
            myUpTickLine = QgsComposerShape(
                myMMOffset, myScaleBarY + myScaleBarHeight - myTickHeight,
                myTickWidth, myTickHeight, self.composition)

            myUpTickLine.setShapeType(QgsComposerShape.Rectangle)
            myUpTickLine.setLineWidth(myLineWidth)
            myUpTickLine.setFrame(False)
            self.composition.addItem(myUpTickLine)
            #
            # Add a tick label
            #
            myLabel = QgsComposerLabel(self.composition)
            myLabel.setFont(myFont)
            myLabel.setText(myRealWorldDistance)
            myLabel.adjustSizeToText()
            myLabel.setItemPosition(myMMOffset - 3, myScaleBarY - myTickHeight)
            myLabel.setFrame(self.showFramesFlag)
            self.composition.addItem(myLabel)