Ejemplo n.º 1
1
def densify(geometry, maxsegmentlength):
    """Densifies geometry vertices, so no segment is longer than maxsegmentlength
    Only implemented for linestring at the time being"""
    g = togeometry(geometry)
    type = QGis.flatType((g.wkbType()))
    if not type == QGis.WKBLineString:
        raise NotImplementedError("Densify is only implemented for LineStrings at the moment")
    input_coords = tocoordinates(g)
    output_coords = []
    maxsegmentlength = float(maxsegmentlength)
    for ix in xrange(len(input_coords) - 1):
        p0 = input_coords[ix]
        p1 = input_coords[ix + 1]
        output_coords.append(QgsPoint(p0))
        # Avoid calculating these values at the cost of performace.
        in_segment = QgsGeometry.fromPolyline([p0, p1])
        in_segment_length = in_segment.length()
        segcount = int(ceil(in_segment_length / maxsegmentlength))
        if segcount > 1:
            new_seg_length = float(in_segment_length) / segcount
            for i in xrange(1,segcount):
                new_p = in_segment.interpolate(new_seg_length * i).asPoint()
                output_coords.append(new_p)
    # Add last coord
    output_coords.append(input_coords[-1])
    return QgsGeometry.fromPolyline(output_coords)
Ejemplo n.º 2
0
 def unitDistance(self, distance):
     units = self.unitsComboBox.currentIndex()
     if units == 0: # meters
         return distance
     elif units == 1: # kilometers
         return distance / 1000.0
     elif units == 2: # feet
         return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Feet)
     elif units == 3: # yards
         return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Feet) / 3.0
     elif units == 4: # miles
         return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.Miles)
     else: # nautical miles
         return distance * QGis.fromUnitToUnitFactor(QGis.Meters, QGis.NauticalMiles)
Ejemplo n.º 3
0
 def conversionToMeters(self, units):
     if units == 2:  # Nautical Miles
         measureFactor = QGis.fromUnitToUnitFactor(QGis.NauticalMiles,
                                                   QGis.Meters)
     elif units == 0:  # Kilometers
         measureFactor = 1000.0
     elif units == 1:  # Meters
         measureFactor = 1.0
     elif units == 3:  # Miles
         measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet,
                                                   QGis.Meters) * 5280.0
     elif units == 4:  # Feet
         measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet, QGis.Meters)
     return measureFactor
Ejemplo n.º 4
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
        tolerance = self.getParameterValue(self.TOLERANCE)

        pointsBefore = 0
        pointsAfter = 0

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.pendingFields().toList(), QGis.flatType(layer.wkbType()), layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features) if len(features) > 0 else 1
        for current, f in enumerate(features):
            featGeometry = f.geometry()
            if featGeometry is not None:
                attrs = f.attributes()
                pointsBefore += self.geomVertexCount(featGeometry)
                newGeometry = featGeometry.simplify(tolerance)
                pointsAfter += self.geomVertexCount(newGeometry)
                feature = QgsFeature()
                feature.setGeometry(newGeometry)
                feature.setAttributes(attrs)
                writer.addFeature(feature)
            progress.setPercentage(int(current * total))

        del writer

        ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                               self.tr('Simplify: Input geometries have been simplified from %s to %s points' % (pointsBefore, pointsAfter)))
Ejemplo n.º 5
0
 def canvasReleaseEvent(self, event):
     """
     When the mouse is clicked
     :param event: mouse event
     """
     types = [QgsWKBTypes.PointZ, QgsWKBTypes.LineStringZ, QgsWKBTypes.CircularStringZ, QgsWKBTypes.CompoundCurveZ,
              QgsWKBTypes.CurvePolygonZ, QgsWKBTypes.PolygonZ]
     display = ""
     for layer in self.canvas().layers():
         if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) in types:
             layerConfig = QgsSnappingUtils.LayerConfig(layer, QgsPointLocator.Vertex, 10, QgsTolerance.Pixels)
             features = Finder.findFeaturesAt(event.mapPoint(), layerConfig, self)
             if len(features) > 0:
                 display += layer.name() + " : \n"
                 for f in features:
                     if f.geometry().type() == QGis.Point:
                         alt = f.geometry().geometry().z()
                     elif f.geometry().type() == QGis.Line:
                         closest = f.geometry().closestVertex(event.mapPoint())
                         alt = f.geometry().geometry().zAt(closest[1])
                     elif f.geometry().type() == QGis.Polygon:
                         self.__iface.messageBar().pushMessage(
                             QCoreApplication.translate("VDLTools", "Polygon not yet implemented"),
                             level=QgsMessageBar.WARNING)
                         continue
                     else:
                         continue
                     display += "    " + str(f.id()) + " | " + str(alt) + " m.\n"
     if display != "":
         QMessageBox.information(None, QCoreApplication.translate("VDLTools", "Id | Elevation"), display)
Ejemplo n.º 6
0
 def get_wkb_type(cls, wkb_type):
     if COMPAT_QGIS_VERSION == 2:
         return QGis.fromOldWkbType(wkb_type) # get new (not deprecated) WKB type for e.g. QgsVectorLayer::wkbType(), QgsGeometry::wkbType(), etc
     elif COMPAT_QGIS_VERSION == 3:
         return wkb_type
     else:
         raise NotImplementedError(COMPAT_QGIS_UNSUPPORTED_MSG)
Ejemplo n.º 7
0
    def create_memory_layer(self, layer):
        """Create an in-memory copy of an existing vector layer."""

        data_provider = layer.dataProvider()

        # create the layer path defining geometry type and reference system
        geometry_type = QGis.vectorGeometryType(layer.geometryType())
        crs_id = layer.crs().authid()
        path = geometry_type + '?crs=' + crs_id + '&index=yes'

        # create the memory layer and get a reference to the data provider
        memory_layer = QgsVectorLayer(path, 'Cartogram', 'memory')
        memory_layer_data_provider = memory_layer.dataProvider()

        # copy all attributes from the source layer to the memory layer
        memory_layer.startEditing()
        memory_layer_data_provider.addAttributes(
            data_provider.fields().toList())
        memory_layer.commitChanges()

        # copy all features from the source layer to the memory layer
        for feature in data_provider.getFeatures():
            memory_layer_data_provider.addFeatures([feature])

        return memory_layer
Ejemplo n.º 8
0
    def action_triggered(self, *args):
        action = self.actiongroup.checkedAction()
        layer = self.activelayercombo.currentLayer()

        self.clear_line()
        if not action:
            return

        if not action == self.measureaction and (not layer or not layer.type() == QgsMapLayer.VectorLayer):
            return

        color = self.current_action_color
        actiondata = {}

        if action == self.measureaction:
            self.measuredialog.show()
            actiondata['mode'] = self.mode
            geomtype = None
            layerid = None
        else:
            self.measuredialog.hide()
            geomtype = QGis.vectorGeometryType(layer.geometryType())
            layerid = layer.id()

        data = dict(action=action.objectName(),
                    layer=layerid,
                    geom=geomtype,
                    actiondata=actiondata,
                    color=color)

        self.earthmine.updateAction(data)
Ejemplo n.º 9
0
    def load_layer_features(self, point=None, layers=None):

        # TODO Move this logic into the viewer and let it track it's position
        if point is None and self.marker.map_pos is None:
            return

        if point is None:
            point = self.marker.map_pos

        area, units = self.distancearea()
        rect = search_area(units, area, point)

        if layers is None:
            layers = self.visible_layers()

        for layer in layers:
            transform = self.coordinatetransform(layer)
            # Transform the rect
            source = self.canvas.mapRenderer().destinationCrs()
            dest = layer.crs()
            recttransform = QgsCoordinateTransform(source, dest)
            rect = recttransform.transformBoundingBox(rect)
            features = list(get_features_in_area(layer, rect, transform, self.canvas.mapSettings()))
            geomtype = layer.geometryType()
            layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype))
            self.viewer.load_features(layerdata, features)
Ejemplo n.º 10
0
    def setEnable(self, layer):
        """
        To check if we can enable the action for the selected layer
        :param layer: selected layer
        """
        if layer is not None\
                and isinstance(layer, QgsVectorLayer)\
                and QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:

            if layer == self.__layer:
                return

            if self.__layer is not None:
                if self.__layer.isEditable():
                    self.__layer.editingStopped.disconnect(self.stopEditing)
                else:
                    self.__layer.editingStarted.disconnect(self.startEditing)
            self.__layer = layer
            if self.__layer.isEditable():
                self.action().setEnabled(True)
                self.__updateList()
                self.__layer.editingStopped.connect(self.stopEditing)
            else:
                self.action().setEnabled(False)
                self.__layer.editingStarted.connect(self.startEditing)
                if self.__canvas.mapTool == self:
                    self.__iface.actionPan().trigger()
                #    self.__canvas.setMapTool(self.__oldTool)
            return
        self.action().setEnabled(False)
        self.removeLayer()
Ejemplo n.º 11
0
def densify(geometry, maxsegmentlength):
    """Densifies geometry vertices, so no segment is longer than maxsegmentlength
    Only implemented for linestring at the time being"""
    g = togeometry(geometry)
    type = QGis.flatType((g.wkbType()))
    if not type == QGis.WKBLineString:
        raise NotImplementedError(
            "Densify is only implemented for LineStrings at the moment")
    input_coords = tocoordinates(g)
    output_coords = []
    maxsegmentlength = float(maxsegmentlength)
    for ix in xrange(len(input_coords) - 1):
        p0 = input_coords[ix]
        p1 = input_coords[ix + 1]
        output_coords.append(QgsPoint(p0))
        # Avoid calculating these values at the cost of performace.
        in_segment = QgsGeometry.fromPolyline([p0, p1])
        in_segment_length = in_segment.length()
        segcount = int(ceil(in_segment_length / maxsegmentlength))
        if segcount > 1:
            new_seg_length = float(in_segment_length) / segcount
            for i in xrange(1, segcount):
                new_p = in_segment.interpolate(new_seg_length * i).asPoint()
                output_coords.append(new_p)
    # Add last coord
    output_coords.append(input_coords[-1])
    return QgsGeometry.fromPolyline(output_coords)
Ejemplo n.º 12
0
def line_locate_point(geometry, point):
    coords = tocoordinates(geometry)

    assert QGis.flatType(
        (geometry.wkbType())) == QGis.WKBLineString, 'Expected a LineString'
    assert len(point) == 2, 'Expected a point'

    sqrddist, closestsegmentpoint, indexofclosestvertexafter = geometry.closestSegmentWithContext(
        point)

    sum_length = 0

    # Length of segments before the segment, where the point is located
    for ix in range(1, indexofclosestvertexafter):
        p0 = coords[ix - 1]
        p1 = coords[ix]
        segment = QgsGeometry.fromPolyline([p0, p1])
        sum_length += segment.length()

    # Part of segment where the points is located
    p0 = coords[indexofclosestvertexafter - 1]
    segment = QgsGeometry.fromPolyline([p0, closestsegmentpoint])
    sum_length += segment.length()

    return sum_length
Ejemplo n.º 13
0
    def __init__(self, table, parent=None):
        TableDataModel.__init__(self, table, parent)

        self.layer = None

        if isinstance(table, LVectorTable):
            self.layer = VLayerRegistry.instance().getLayer(table.name)
        else:
            self.layer = VLayerRegistry.instance().getLayer(table)

        if not self.layer:
            return
        # populate self.resdata
        self.resdata = []
        for f in self.layer.getFeatures():
            a = f.attributes()
            # add the geometry type
            if f.geometry():
                a.append(QgsWKBTypes.displayString(QGis.fromOldWkbType(f.geometry().wkbType())))
            else:
                a.append('None')
            self.resdata.append(a)

        self.fetchedFrom = 0
        self.fetchedCount = len(self.resdata)
Ejemplo n.º 14
0
    def action_triggered(self, *args):
        action = self.actiongroup.checkedAction()
        layer = self.activelayercombo.currentLayer()

        self.clear_line()
        if not action:
            return

        if not action == self.measureaction and (
                not layer or not layer.type() == QgsMapLayer.VectorLayer):
            return

        color = self.current_action_color
        actiondata = {}

        if action == self.measureaction:
            self.measuredialog.show()
            actiondata['mode'] = self.mode
            geomtype = None
            layerid = None
        else:
            self.measuredialog.hide()
            geomtype = QGis.vectorGeometryType(layer.geometryType())
            layerid = layer.id()

        data = dict(action=action.objectName(),
                    layer=layerid,
                    geom=geomtype,
                    actiondata=actiondata,
                    color=color)

        self.earthmine.updateAction(data)
Ejemplo n.º 15
0
    def setEnable(self, layer):
        """
        To check if we can enable the action for the selected layer
        :param layer: selected layer
        """
        if layer is not None and layer.type() == QgsMapLayer.VectorLayer\
                and QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:
            if layer == self.__layer:
                return

            if self.__layer is not None:
                if self.__layer.isEditable():
                    Signal.safelyDisconnect(self.__layer.editingStopped, self.stopEditing)
                else:
                    Signal.safelyDisconnect(self.__layer.editingStarted, self.startEditing)
            self.__layer = layer
            if self.__layer.isEditable():
                self.action().setEnabled(True)
                self.__layer.editingStopped.connect(self.stopEditing)
            else:
                self.action().setEnabled(False)
                self.__layer.editingStarted.connect(self.startEditing)
                if self.canvas().mapTool() == self:
                    self.__iface.actionPan().trigger()
            return
        self.action().setEnabled(False)
        self.__removeLayer()
Ejemplo n.º 16
0
    def load_layer_features(self, point=None, layers=None):

        # TODO Move this logic into the viewer and let it track it's position
        if point is None and self.marker.map_pos is None:
            return

        if point is None:
            point = self.marker.map_pos

        area, units = self.distancearea()
        rect = search_area(units, area, point)

        if layers is None:
            layers = self.visible_layers()

        for layer in layers:
            transform = self.coordinatetransform(layer)
            # Transform the rect
            source = self.canvas.mapRenderer().destinationCrs()
            dest = layer.crs()
            recttransform = QgsCoordinateTransform(source, dest)
            rect = recttransform.transformBoundingBox(rect)
            features = list(
                get_features_in_area(layer, rect, transform,
                                     self.canvas.mapSettings()))
            geomtype = layer.geometryType()
            layerdata = dict(id=layer.id(),
                             geomtype=QGis.vectorGeometryType(geomtype))
            self.viewer.load_features(layerdata, features)
Ejemplo n.º 17
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(
            self.INPUT))
        tolerance = self.getParameterValue(self.TOLERANCE)

        pointsBefore = 0
        pointsAfter = 0

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.pendingFields().toList(), QGis.flatType(layer.wkbType()),
            layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features) if len(features) > 0 else 1
        for current, f in enumerate(features):
            featGeometry = f.geometry()
            if featGeometry is not None:
                attrs = f.attributes()
                pointsBefore += self.geomVertexCount(featGeometry)
                newGeometry = featGeometry.simplify(tolerance)
                pointsAfter += self.geomVertexCount(newGeometry)
                feature = QgsFeature()
                feature.setGeometry(newGeometry)
                feature.setAttributes(attrs)
                writer.addFeature(feature)
            progress.setPercentage(int(current * total))

        del writer

        ProcessingLog.addToLog(
            ProcessingLog.LOG_INFO,
            self.
            tr('Simplify: Input geometries have been simplified from %s to %s points'
               % (pointsBefore, pointsAfter)))
Ejemplo n.º 18
0
    def setEnable(self, layer):
        """
        To check if we can enable the action for the selected layer
        :param layer: selected layer
        """
        if layer is not None and layer.type() == QgsMapLayer.VectorLayer\
                and QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:
            if layer == self.__layer:
                return

            if self.__layer is not None:
                if self.__layer.isEditable():
                    Signal.safelyDisconnect(self.__layer.editingStopped,
                                            self.stopEditing)
                else:
                    Signal.safelyDisconnect(self.__layer.editingStarted,
                                            self.startEditing)
            self.__layer = layer
            if self.__layer.isEditable():
                self.action().setEnabled(True)
                self.__layer.editingStopped.connect(self.stopEditing)
            else:
                self.action().setEnabled(False)
                self.__layer.editingStarted.connect(self.startEditing)
                if self.canvas().mapTool() == self:
                    self.__iface.actionPan().trigger()
            return
        self.action().setEnabled(False)
        self.__removeLayer()
Ejemplo n.º 19
0
    def report(self, rulename, typeinfo, message, geometry, level):
        if geometry:
            try:
                geometry = togeometry(geometry)
            except TypeError:
                geometry = None

        fields = [
            ('rulename', unicode(rulename).encode('utf-8')),
            ('objecttype', unicode(typeinfo).encode('utf-8')),
            ('message', unicode(message).encode('utf-8')),
            ('level', unicode(level).encode('utf-8'))
        ]

        # QGis.flatType if we don't care about 25D and whatnot
        if geometry is None:
            print 'XXXXX text output xxxxx', message
            self.db.add_feature_to_layer(
                self.text_table,
                fields,
                None
            )
        elif QGis.flatType(geometry.wkbType()) == QGis.WKBLineString:
            if geometry.length() < 0.001:
                # Lines with length 0 tends to crash spatialite. Report as point instead
                self.report(rulename, typeinfo, message, geometry.centroid(), level)
            else:
                self.db.add_feature_to_layer(
                    self.linestring_table,
                    fields,
                    geometry
                )
        elif QGis.flatType((geometry.wkbType())) == QGis.WKBPoint:
            self.db.add_feature_to_layer(
                self.point_table,
                fields,
                geometry
            )

        elif QGis.flatType((geometry.wkbType())) == QGis.WKBPolygon:
            self.db.add_feature_to_layer(
                self.polygon_table,
                fields,
                geometry
            )
Ejemplo n.º 20
0
def tocoordinates(feature):
    g = togeometry(feature)
    type = QGis.flatType((g.wkbType()))
    if type == QGis.WKBPoint:
        return g.asPoint()
    if type == QGis.WKBLineString:
        return g.asPolyline()
    if type == QGis.WKBPolygon:
        return g.asPolygon()
    raise TypeError("Unknown geometry type: " + str(type))
Ejemplo n.º 21
0
def tocoordinates(feature):
    g = togeometry(feature)
    type = QGis.flatType((g.wkbType()))
    if type == QGis.WKBPoint:
        return g.asPoint()
    if type == QGis.WKBLineString:
        return g.asPolyline()
    if type == QGis.WKBPolygon:
        return g.asPolygon()
    raise TypeError("Unknown geometry type: " + str(type))
Ejemplo n.º 22
0
    def layer_feature_added(self, layer, featureid):
        if not self.viewer:
            return

        feature = layer.getFeatures(QgsFeatureRequest(featureid)).next()
        renderer = layer.rendererV2()
        transform = self.coordinatetransform(layer)
        featuredata = to_feature_data(layer.id(), feature, renderer, transform)
        geomtype = layer.geometryType()
        layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype))
        self.viewer.load_features(layerdata, featuredata)
Ejemplo n.º 23
0
 def __getPointLayers(self):
     """
     To get all points layers that can be used
     :return: layers list
     """
     layerList = []
     for layer in self.__iface.mapCanvas().layers():
         if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(
                 layer.wkbType()) == QgsWKBTypes.PointZ:
             layerList.append(layer)
     return layerList
Ejemplo n.º 24
0
def toflatcoordinates(feature):
    """Returns a flat list of all coordinates in the geometry"""
    g = togeometry(feature)
    type = QGis.flatType((g.wkbType()))
    if type == QGis.WKBPoint:
        return [g.asPoint()]
    if type == QGis.WKBLineString:
        return g.asPolyline()
    if type == QGis.WKBPolygon:
        return [coord for ring in g.asPolygon() for coord in ring]
    raise TypeError("Unknown geometry type: " + str(type))
Ejemplo n.º 25
0
def toflatcoordinates(feature):
    """Returns a flat list of all coordinates in the geometry"""
    g = togeometry(feature)
    type = QGis.flatType((g.wkbType()))
    if type == QGis.WKBPoint:
        return [g.asPoint()]
    if type == QGis.WKBLineString:
        return g.asPolyline()
    if type == QGis.WKBPolygon:
        return [coord for ring in g.asPolygon() for coord in ring]
    raise TypeError("Unknown geometry type: " + str(type))
Ejemplo n.º 26
0
    def processAlgorithm(self, progress):
        layerA = dataobjects.getObjectFromUri(
            self.getParameterValue(Difference.INPUT))
        layerB = dataobjects.getObjectFromUri(
            self.getParameterValue(Difference.OVERLAY))
        ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID)

        geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType()))
        writer = self.getOutputFromName(
            Difference.OUTPUT).getVectorWriter(layerA.pendingFields(),
                                               geomType,
                                               layerA.crs())

        outFeat = QgsFeature()
        index = vector.spatialindex(layerB)
        selectionA = vector.features(layerA)
        total = 100.0 / len(selectionA) if len(selectionA) > 0 else 1
        for current, inFeatA in enumerate(selectionA):
            add = True
            geom = QgsGeometry(inFeatA.geometry())
            diff_geom = QgsGeometry(geom)
            attrs = inFeatA.attributes()
            intersections = index.intersects(geom.boundingBox())
            for i in intersections:
                request = QgsFeatureRequest().setFilterFid(i)
                inFeatB = layerB.getFeatures(request).next()
                tmpGeom = QgsGeometry(inFeatB.geometry())
                if diff_geom.intersects(tmpGeom):
                    diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
                    if diff_geom.isGeosEmpty():
                        ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                               self.tr('Feature with NULL geometry found.'))
                    if not diff_geom.isGeosValid():
                        if ignoreInvalid:
                            ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                                   self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.'))
                            add = False
                        else:
                            raise GeoAlgorithmExecutionException(self.tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag'))
                        break

            if add:
                try:
                    outFeat.setGeometry(diff_geom)
                    outFeat.setAttributes(attrs)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(ProcessingLog.LOG_WARNING,
                                           self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
                    continue

            progress.setPercentage(int(current * total))

        del writer
Ejemplo n.º 27
0
    def layer_feature_added(self, layer, featureid):
        if not self.viewer:
            return

        feature = layer.getFeatures(QgsFeatureRequest(featureid)).next()
        renderer = layer.rendererV2()
        transform = self.coordinatetransform(layer)
        featuredata = to_feature_data(layer.id(), feature, renderer, transform)
        geomtype = layer.geometryType()
        layerdata = dict(id=layer.id(),
                         geomtype=QGis.vectorGeometryType(geomtype))
        self.viewer.load_features(layerdata, featuredata)
Ejemplo n.º 28
0
 def __getOtherLayers(self):
     """
     To get all points layers that can be used
     :return: layers list
     """
     layerList = []
     types = [QgsWKBTypes.PointZ, QgsWKBTypes.LineStringZ, QgsWKBTypes.CircularStringZ, QgsWKBTypes.CompoundCurveZ,
              QgsWKBTypes.CurvePolygonZ, QgsWKBTypes.PolygonZ]
     for layer in self.canvas().layers():
         if layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) in types:
             layerList.append(layer)
     return layerList
Ejemplo n.º 29
0
    def _calc_size(self):
        realSize = self.realsize
        canvaswidth = self.canvas.width()
        mapunitsperpixel = abs(self.canvas.mapUnitsPerPixel())
        mapunits = self.canvas.mapUnits()
        prefered_units = roam.config.settings.get("prefer_units", "meters")
        newunits = QGis.fromLiteral(prefered_units, QGis.Meters)
        mapunitsperpixel *= QGis.fromUnitToUnitFactor(mapunits, newunits)
        mapunits = newunits

        # Convert the real distance into pixels
        barwidth = realSize / mapunitsperpixel

        if barwidth < 30:
            barwidth = canvaswidth / 4

        while barwidth > canvaswidth / 3:
            barwidth /= 3

        realSize = barwidth * mapunitsperpixel

        # Round
        powerof10 = math.floor(math.log10(realSize))
        scaler = math.pow(10.0, powerof10)
        realSize = round(realSize / scaler) * scaler
        barwidth = realSize / mapunitsperpixel
        label, realSize = self._label_size(mapunits, realSize)
        metrics = QFontMetrics(self.font)
        fontwidth = metrics.width(label)
        fontheight = metrics.height()

        sizelabel = QLocale.system().toString(realSize)
        sizelabel = "{} {}".format(sizelabel, label)

        barwidth = self._adjust_bar_size(barwidth, mapunits)
        barwidth = barwidth + fontwidth

        return barwidth, realSize, sizelabel, (fontwidth, fontheight)
Ejemplo n.º 30
0
    def _calc_size(self):
        realSize = self.realsize
        canvaswidth = self.canvas.width()
        mapunitsperpixel = abs(self.canvas.mapUnitsPerPixel())
        mapunits = self.canvas.mapUnits()
        prefered_units = roam.config.settings.get("prefer_units", "meters")
        newunits = QGis.fromLiteral(prefered_units, QGis.Meters)
        mapunitsperpixel *= QGis.fromUnitToUnitFactor(mapunits, newunits)
        mapunits = newunits

        # Convert the real distance into pixels
        barwidth = realSize / mapunitsperpixel

        if barwidth < 30:
            barwidth = canvaswidth / 4

        while barwidth > canvaswidth / 3:
            barwidth /= 3

        realSize = barwidth * mapunitsperpixel

        # Round
        powerof10 = math.floor(math.log10(realSize))
        scaler = math.pow(10.0, powerof10)
        realSize = round(realSize / scaler) * scaler
        barwidth = realSize / mapunitsperpixel
        label, realSize = self._label_size(mapunits, realSize)
        metrics = QFontMetrics(self.font)
        fontwidth = metrics.width(label)
        fontheight = metrics.height()

        sizelabel = QLocale.system().toString(realSize)
        sizelabel = "{} {}".format(sizelabel, label)

        barwidth = self._adjust_bar_size(barwidth, mapunits)
        barwidth = barwidth + fontwidth

        return barwidth, realSize, sizelabel, (fontwidth, fontheight)
Ejemplo n.º 31
0
def to_feature_data(layerid, feature, renderer, transform):
    """
    Transform the feature into the data for the viewer to use.
    :param feature: QgsFeature
    :param renderer:
    :param transform:
    :return:
    """
    def polylinenodes(polyline):
        nodes = []
        for point in polyline:
            point = transform.transform(
                point, QgsCoordinateTransform.ReverseTransform)
            location = dict(lat=point.y(), lng=point.x())
            nodes.append(location)
        return nodes

    geom = feature.geometry()
    geomtype = geom.type()
    featuredata = []
    data = dict(id=feature.id(),
                layerid=layerid,
                color=get_color(renderer, feature),
                geomtype=QGis.vectorGeometryType(geomtype))
    if geomtype == QGis.Point:
        geom = geom.asPoint()
        point = transform.transform(geom,
                                    QgsCoordinateTransform.ReverseTransform)
        try:
            z = feature['Z']
            if not z:
                z = 0
        except KeyError:
            z = 0
        location = dict(lat=point.y(), lng=point.x(), z=z)
        data['nodes'] = [location]
        featuredata.append(data)
    elif geomtype == QGis.Line:
        if geom.isMultipart():
            # Copy the data for each polyline
            for polyline in geom.asMultiPolyline():
                newdata = copy.copy(data)
                newdata['nodes'] = polylinenodes(polyline)
                featuredata.append(newdata)
        else:
            data['nodes'] = polylinenodes(geom.asPolyline())
            featuredata.append(data)
    return featuredata
Ejemplo n.º 32
0
 def setEnable(self, layer):
     """
     To check if we can enable the action for the selected layer
     :param layer: selected layer
     """
     if layer is not None and layer.type() == QgsMapLayer.VectorLayer and QGis.fromOldWkbType(layer.wkbType()) == \
             QgsWKBTypes.LineStringZ:
         self.__lineLayer = layer
         self.action().setEnabled(True)
         return
     self.action().setEnabled(False)
     if self.canvas().mapTool() == self:
         self.__iface.actionPan().trigger()
     if self.__dockWdg is not None:
         self.__dockWdg.close()
     self.__lineLayer = None
Ejemplo n.º 33
0
 def setEnable(self, layer):
     """
     To check if we can enable the action for the selected layer
     :param layer: selected layer
     """
     if layer is not None and layer.type() == QgsMapLayer.VectorLayer and \
                     QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:
         self.__lineLayer = layer
         self.action().setEnabled(True)
         return
     self.action().setEnabled(False)
     if self.__canvas.mapTool == self:
         self.__iface.actionPan().trigger()
     #    self.__canvas.setMapTool(self.__oldTool)
     if self.__dockWdg is not None:
         self.__dockWdg.close()
     self.__lineLayer = None
Ejemplo n.º 34
0
    def get_layer_geometry(layer):
        """Get layer geometry for vector layers.

        From layer object extract which geometry type it has. Is it point,
        line or polygon.
        """

        if layer.type() == QgsMapLayer.RasterLayer:
            return ['raster', 999]

        if ISQGIS3:
            wkb_type = QgsWkbTypes.flatType(layer.wkbType())
            point_type = QgsWkbTypes.Point
            line_string_type = QgsWkbTypes.LineString
            polygon_type = QgsWkbTypes.Polygon
            multi_point_type = QgsWkbTypes.MultiPoint
            multi_line_string_type = QgsWkbTypes.MultiLineString
            multi_polygon_type = QgsWkbTypes.MultiPolygon
        else:
            wkb_type = QGis.flatType(layer.wkbType())
            point_type = QGis.WKBPoint
            line_string_type = QGis.WKBLineString
            polygon_type = QGis.WKBPolygon
            multi_point_type = QGis.WKBMultiPoint
            multi_line_string_type = QGis.WKBMultiLineString
            multi_polygon_type = QGis.WKBMultiPolygon
        LOGGER.info('type {}', layer.wkbType())

        geometry = [None, 100]

        if wkb_type == point_type:
            geometry = ['point', 1]
        if wkb_type == line_string_type:
            geometry = ['line', 2]
        if wkb_type == polygon_type:
            geometry = ['polygon', 3]
        if wkb_type == multi_point_type:
            geometry = ['point', 4]
        if wkb_type == multi_line_string_type:
            geometry = ['line', 5]
        if wkb_type == multi_polygon_type:
            geometry = ['polygon', 6]
        if wkb_type == 100:
            LOGGER.info('Layer is a data-only layer')
        return geometry
Ejemplo n.º 35
0
def line_locate_point(geometry, point):
    coords = tocoordinates(geometry)

    assert QGis.flatType((geometry.wkbType())) == QGis.WKBLineString, 'Expected a LineString'
    assert len(point) == 2, 'Expected a point'

    sqrddist, closestsegmentpoint, indexofclosestvertexafter = geometry.closestSegmentWithContext(point)

    sum_length = 0

    # Length of segments before the segment, where the point is located
    for ix in range(1, indexofclosestvertexafter):
        p0 = coords[ix - 1]
        p1 = coords[ix]
        segment = QgsGeometry.fromPolyline([p0, p1])
        sum_length += segment.length()

    # Part of segment where the points is located
    p0 = coords[indexofclosestvertexafter - 1]
    segment = QgsGeometry.fromPolyline([p0, closestsegmentpoint])
    sum_length += segment.length()

    return sum_length
Ejemplo n.º 36
0
    def __init__(self, iface, memoryPointsLayer, memoryLinesLayer,
                 importConfigTable, importUriDb, importSchemaDb,
                 controlConfigTable, controlUriDb, controlSchemaDb, mntUrl,
                 refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer,
                 pipeDiam, moreTools):
        """
        Constructor
        :param iface: interface
        :param memoryPointsLayer: working memory points layer
        :param memoryLinesLayer: working memory lines layer
        :param importConfigTable: config table selected for import
        :param importUriDb: database for import
        :param importSchemaDb: db schema for import
        :param controlConfigTable: config table selected for control
        :param controlUriDb: database for control
        :param controlSchemaDb: db schema for control
        :param mntUrl: url to get mnt
        :param refLayers: reference layers for drawdown
        :param adjLayers: adjustement layers for drawdown
        :param levelAtt: level attribute for drawdown
        :param levelVal: level value for drawdown
        :param drawdowmLayer: line layer for drawdown
        :param pipeDiam: pipe diameter for drawdown
        :param moreTools: if more tools or not
        """
        QDialog.__init__(self)
        self.__iface = iface
        self.__memoryPointsLayer = memoryPointsLayer
        self.__memoryLinesLayer = memoryLinesLayer
        self.__importConfigTable = importConfigTable
        self.__importUriDb = importUriDb
        self.__importSchemaDb = importSchemaDb
        self.__controlConfigTable = controlConfigTable
        self.__controlUriDb = controlUriDb
        self.__controlSchemaDb = controlSchemaDb
        self.__mntUrl = mntUrl
        self.__refLayers = refLayers
        self.__adjLayers = adjLayers
        self.__levelAtt = levelAtt
        self.__levelVal = levelVal
        self.__drawdowmLayer = drawdowmLayer
        self.__pipeDiam = pipeDiam
        self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings"))
        self.__pointsLayers = []
        self.__linesLayers = []
        self.__refAvailableLayers = []
        self.__drawdownLayers = []
        self.__tables = []
        self.__schemas = []
        self.__pipeDiamFields = []
        self.__levelAttFields = []
        self.__dbs = DBConnector.getUsedDatabases()

        self.__refLabels = []
        self.__refChecks = []
        self.__adjChecks = []

        for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()):
            if layer is not None and layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() == "memory":
                    if layer.geometryType() == QGis.Point:
                        self.__pointsLayers.append(layer)
                    if layer.geometryType() == QGis.Line:
                        self.__linesLayers.append(layer)
                if QGis.fromOldWkbType(
                        layer.wkbType()) == QgsWKBTypes.LineStringZ:
                    self.__drawdownLayers.append(layer)
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ:
                    self.__refAvailableLayers.append(layer)

        self.resize(600, 500)
        self.__layout = QGridLayout()
        self.__scrollLayout = QGridLayout()
        line = 0

        intersectLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Intersect "))
        self.__scrollLayout.addWidget(intersectLabel, line, 0)

        line += 1

        pointLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Working points layer : "))
        self.__scrollLayout.addWidget(pointLabel, line, 1)

        self.__pointCombo = QComboBox()
        self.__pointCombo.setMinimumHeight(20)
        self.__pointCombo.setMinimumWidth(50)
        self.__pointCombo.addItem("")
        for layer in self.__pointsLayers:
            self.__pointCombo.addItem(layer.name())
        self.__scrollLayout.addWidget(self.__pointCombo, line, 2)
        self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged)
        if self.__memoryPointsLayer is not None:
            if self.__memoryPointsLayer in self.__pointsLayers:
                self.__pointCombo.setCurrentIndex(
                    self.__pointsLayers.index(self.__memoryPointsLayer) + 1)

        line += 1

        lineLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Working lines layer : "))
        self.__scrollLayout.addWidget(lineLabel, line, 1)

        self.__lineCombo = QComboBox()
        self.__lineCombo.setMinimumHeight(20)
        self.__lineCombo.setMinimumWidth(50)
        self.__lineCombo.addItem("")
        for layer in self.__linesLayers:
            self.__lineCombo.addItem(layer.name())
        self.__scrollLayout.addWidget(self.__lineCombo, line, 2)
        self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged)
        if self.__memoryLinesLayer is not None:
            if self.__memoryLinesLayer in self.__linesLayers:
                self.__lineCombo.setCurrentIndex(
                    self.__linesLayers.index(self.__memoryLinesLayer) + 1)

        line += 1

        profilesLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Profiles "))
        self.__scrollLayout.addWidget(profilesLabel, line, 0)

        line += 1

        mntLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Url for MNT : "))
        self.__scrollLayout.addWidget(mntLabel, line, 1)

        self.__mntText = QLineEdit()
        if self.__mntUrl is None or self.__mntUrl == "None":
            self.__mntText.insert(
                'https://map.lausanne.ch/prod/wsgi/profile.json')
        else:
            self.__mntText.insert(self.__mntUrl)
        self.__mntText.setMinimumHeight(20)
        self.__mntText.setMinimumWidth(100)
        self.__scrollLayout.addWidget(self.__mntText, line, 2)

        line += 1

        ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown "))
        self.__scrollLayout.addWidget(ddLabel, line, 0)

        line += 1

        self.__scrollLayout.addWidget(
            QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1)

        namesLayout = QHBoxLayout()
        namesWidget = QWidget()
        namesLayout.addWidget(
            QLabel(QCoreApplication.translate("VDLTools", "Reference")))
        namesLayout.addWidget(
            QLabel(QCoreApplication.translate("VDLTools", "Adjustable")))
        namesLayout.setContentsMargins(0, 0, 0, 0)
        namesWidget.setLayout(namesLayout)
        self.__scrollLayout.addWidget(namesWidget, line, 2)

        line += 1

        for layer in self.__refAvailableLayers:
            refLabel = QLabel("  - " + layer.name())
            self.__refLabels.append(refLabel)
            self.__scrollLayout.addWidget(refLabel, line, 1)

            checksLayout = QHBoxLayout()
            checksLayout.setContentsMargins(0, 0, 0, 0)
            checksWidget = QWidget()

            refCheck = QCheckBox()
            self.__refChecks.append(refCheck)
            refCheck.stateChanged.connect(self.__refBoxesChanged)
            checksLayout.addWidget(refCheck)

            adjCheck = QCheckBox()
            self.__adjChecks.append(adjCheck)
            checksLayout.addWidget(adjCheck)

            checksWidget.setLayout(checksLayout)
            self.__scrollLayout.addWidget(checksWidget, line, 2)

            line += 1

        levelAttLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Code(s) on pipe : "))
        self.__scrollLayout.addWidget(levelAttLabel, line, 1)

        self.__levelAttCombo = QComboBox()
        self.__levelAttCombo.setMinimumHeight(20)
        self.__levelAttCombo.setMinimumWidth(50)
        self.__levelAttCombo.addItem("")
        self.__scrollLayout.addWidget(self.__levelAttCombo, line, 2)

        self.__levelAttCombo.currentIndexChanged.connect(
            self.__levelAttComboChanged)

        i = 0
        for layer in self.__refAvailableLayers:
            if layer in self.__refLayers:
                self.__refChecks[i].setChecked(True)
            if layer in self.__adjLayers:
                self.__adjChecks[i].setChecked(True)
            i += 1

        line += 1

        levelValLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Point code attribute : "))
        self.__scrollLayout.addWidget(levelValLabel, line, 1)

        self.__levelValText = QLineEdit()
        if self.__levelVal is not None and self.__levelVal != "None":
            self.__levelValText.insert(self.__levelVal)
        self.__levelValText.setMinimumHeight(20)
        self.__levelValText.setMinimumWidth(100)
        self.__scrollLayout.addWidget(self.__levelValText, line, 2)

        line += 1

        drawdownLabel = QLabel(
            QCoreApplication.translate("VDLTools", "drawdown layer : "))
        self.__scrollLayout.addWidget(drawdownLabel, line, 1)

        self.__drawdownCombo = QComboBox()
        self.__drawdownCombo.setMinimumHeight(20)
        self.__drawdownCombo.setMinimumWidth(50)
        self.__drawdownCombo.addItem("")
        for layer in self.__drawdownLayers:
            self.__drawdownCombo.addItem(layer.name())
        self.__scrollLayout.addWidget(self.__drawdownCombo, line, 2)

        line += 1

        pipeDiamLabel = QLabel(
            QCoreApplication.translate("VDLTools",
                                       "Pipe diameter attribute [cm] : "))
        self.__scrollLayout.addWidget(pipeDiamLabel, line, 1)

        self.__pipeDiamCombo = QComboBox()
        self.__pipeDiamCombo.setMinimumHeight(20)
        self.__pipeDiamCombo.setMinimumWidth(50)
        self.__pipeDiamCombo.addItem("")
        self.__scrollLayout.addWidget(self.__pipeDiamCombo, line, 2)

        self.__drawdownCombo.currentIndexChanged.connect(
            self.__drawdownComboChanged)
        self.__pipeDiamCombo.currentIndexChanged.connect(
            self.__pipeDiamComboChanged)

        if self.__drawdowmLayer is not None:
            if self.__drawdowmLayer in self.__drawdownLayers:
                self.__drawdownCombo.setCurrentIndex(
                    self.__drawdownLayers.index(self.__drawdowmLayer) + 1)

        line += 1

        controlLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Control "))
        self.__scrollLayout.addWidget(controlLabel, line, 0)

        line += 1

        controlDbLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Control database : "))
        self.__scrollLayout.addWidget(controlDbLabel, line, 1)

        self.__controlDbCombo = QComboBox()
        self.__controlDbCombo.setMinimumHeight(20)
        self.__controlDbCombo.setMinimumWidth(50)
        self.__controlDbCombo.addItem("")
        for db in list(self.__dbs.keys()):
            self.__controlDbCombo.addItem(db)
        self.__scrollLayout.addWidget(self.__controlDbCombo, line, 2)

        line += 1

        controlSchemaLabel = QLabel(
            QCoreApplication.translate("VDLTools",
                                       "Control database schema : "))
        self.__scrollLayout.addWidget(controlSchemaLabel, line, 1)

        self.__controlSchemaCombo = QComboBox()
        self.__controlSchemaCombo.setMinimumHeight(20)
        self.__controlSchemaCombo.setMinimumWidth(50)
        self.__controlSchemaCombo.addItem("")
        self.__scrollLayout.addWidget(self.__controlSchemaCombo, line, 2)

        line += 1

        controlTableLabel = QLabel(
            QCoreApplication.translate("VDLTools", "Control config table : "))
        self.__scrollLayout.addWidget(controlTableLabel, line, 1)

        self.__controlTableCombo = QComboBox()
        self.__controlTableCombo.setMinimumHeight(20)
        self.__controlTableCombo.setMinimumWidth(50)
        self.__controlTableCombo.addItem("")
        self.__scrollLayout.addWidget(self.__controlTableCombo, line, 2)

        self.__controlDbCombo.currentIndexChanged.connect(
            self.__controlDbComboChanged)
        self.__controlSchemaCombo.currentIndexChanged.connect(
            self.__controlSchemaComboChanged)
        self.__controlTableCombo.currentIndexChanged.connect(
            self.__controlTableComboChanged)

        if self.__controlUriDb is not None:
            if self.__controlUriDb.database() in list(self.__dbs.keys()):
                self.__controlDbCombo.setCurrentIndex(
                    list(self.__dbs.keys()).index(
                        self.__controlUriDb.database()) + 1)

        if moreTools:
            line += 1

            importLabel = QLabel(
                QCoreApplication.translate("VDLTools", "Import "))
            self.__scrollLayout.addWidget(importLabel, line, 0)

            line += 1

            importDbLabel = QLabel(
                QCoreApplication.translate("VDLTools", "Import database : "))
            self.__scrollLayout.addWidget(importDbLabel, line, 1)

            self.__importDbCombo = QComboBox()
            self.__importDbCombo.setMinimumHeight(20)
            self.__importDbCombo.setMinimumWidth(50)
            self.__importDbCombo.addItem("")
            for db in list(self.__dbs.keys()):
                self.__importDbCombo.addItem(db)
            self.__scrollLayout.addWidget(self.__importDbCombo, line, 2)

            line += 1

            importSchemaLabel = QLabel(
                QCoreApplication.translate("VDLTools",
                                           "Import database schema : "))
            self.__scrollLayout.addWidget(importSchemaLabel, line, 1)

            self.__importSchemaCombo = QComboBox()
            self.__importSchemaCombo.setMinimumHeight(20)
            self.__importSchemaCombo.setMinimumWidth(50)
            self.__importSchemaCombo.addItem("")
            self.__scrollLayout.addWidget(self.__importSchemaCombo, line, 2)

            line += 1

            importTableLabel = QLabel(
                QCoreApplication.translate("VDLTools",
                                           "Import config table : "))
            self.__scrollLayout.addWidget(importTableLabel, line, 1)

            self.__importTableCombo = QComboBox()
            self.__importTableCombo.setMinimumHeight(20)
            self.__importTableCombo.setMinimumWidth(50)
            self.__importTableCombo.addItem("")
            self.__scrollLayout.addWidget(self.__importTableCombo, line, 2)

            self.__importDbCombo.currentIndexChanged.connect(
                self.__importDbComboChanged)
            self.__importSchemaCombo.currentIndexChanged.connect(
                self.__importSchemaComboChanged)
            self.__importTableCombo.currentIndexChanged.connect(
                self.__importTableComboChanged)

            if self.__importUriDb is not None:
                if self.__importUriDb.database() in list(self.__dbs.keys()):
                    self.__importDbCombo.setCurrentIndex(
                        list(self.__dbs.keys()).index(
                            self.__importUriDb.database()) + 1)

        else:
            self.__importDbCombo = None
            self.__importSchemaCombo = None
            self.__importTableCombo = None

        widget = QWidget()
        widget.setLayout(self.__scrollLayout)

        scroll = QScrollArea()
        scroll.setWidgetResizable(True)
        scroll.setWidget(widget)

        self.__layout.addWidget(scroll, 1, 0, 1, 2)

        self.__okButton = QPushButton(
            QCoreApplication.translate("VDLTools", "OK"))
        self.__okButton.setMinimumHeight(20)
        self.__okButton.setMinimumWidth(100)

        self.__cancelButton = QPushButton(
            QCoreApplication.translate("VDLTools", "Cancel"))
        self.__cancelButton.setMinimumHeight(20)
        self.__cancelButton.setMinimumWidth(100)

        self.__layout.addWidget(self.__okButton, 100, 0)
        self.__layout.addWidget(self.__cancelButton, 100, 1)
        self.setLayout(self.__layout)
Ejemplo n.º 37
0
    def processAlgorithm(self, progress):
        source_layer = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.INPUT))
        mask_layer = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.OVERLAY))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            source_layer.fields(),
            QgsWKBTypes.multiType(QGis.fromOldWkbType(source_layer.wkbType())),
            source_layer.crs())

        # first build up a list of clip geometries
        clip_geoms = []
        for maskFeat in vector.features(mask_layer, QgsFeatureRequest().setSubsetOfAttributes([])):
            clip_geoms.append(QgsGeometry(maskFeat.constGeometry()))

        # are we clipping against a single feature? if so, we can show finer progress reports
        if len(clip_geoms) > 1:
            combined_clip_geom = QgsGeometry.unaryUnion(clip_geoms)
            single_clip_feature = False
        else:
            combined_clip_geom = clip_geoms[0]
            single_clip_feature = True

        # use prepared geometries for faster intersection tests
        engine = QgsGeometry.createGeometryEngine(combined_clip_geom.geometry())
        engine.prepareGeometry()

        tested_feature_ids = set()

        for i, clip_geom in enumerate(clip_geoms):
            input_features = [f for f in vector.features(source_layer, QgsFeatureRequest().setFilterRect(clip_geom.boundingBox()))]

            if not input_features:
                continue

            if single_clip_feature:
                total = 100.0 / len(input_features) if len(input_features) > 0 else 1
            else:
                total = 0

            for current, in_feat in enumerate(input_features):
                if not in_feat.constGeometry():
                    continue

                if in_feat.id() in tested_feature_ids:
                    # don't retest a feature we have already checked
                    continue

                tested_feature_ids.add(in_feat.id())

                if not engine.intersects(in_feat.constGeometry().geometry()):
                    continue

                if not engine.contains(in_feat.constGeometry().geometry()):
                    cur_geom = QgsGeometry(in_feat.constGeometry())
                    new_geom = combined_clip_geom.intersection(cur_geom)
                    if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
                        int_com = in_feat.constGeometry().combine(new_geom)
                        int_sym = in_feat.constGeometry().symDifference(new_geom)
                        if not int_com or not int_sym:
                            ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                                   self.tr('GEOS geoprocessing error: One or more '
                                                           'input features have invalid geometry.'))
                        else:
                            new_geom = int_com.difference(int_sym)
                            if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
                                ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                                       self.tr('GEOS geoprocessing error: One or more '
                                                               'input features have invalid geometry.'))
                else:
                    # clip geometry totally contains feature geometry, so no need to perform intersection
                    new_geom = QgsGeometry(in_feat.constGeometry())

                try:
                    out_feat = QgsFeature()
                    out_feat.setGeometry(new_geom)
                    out_feat.setAttributes(in_feat.attributes())
                    writer.addFeature(out_feat)
                except:
                    ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                           self.tr('Feature geometry error: One or more '
                                                   'output features ignored due to '
                                                   'invalid geometry.'))
                    continue

                if single_clip_feature:
                    progress.setPercentage(int(current * total))

            if not single_clip_feature:
                # coarse progress report for multiple clip geometries
                progress.setPercentage(100.0 * i / len(clip_geoms))

        del writer
    def processAlgorithm(self, progress):
        layerA = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        layerB = dataobjects.getObjectFromUri(
            self.getParameterValue(self.OVERLAY))

        geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType()))
        fields = vector.combineVectorFields(layerA, layerB)
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, geomType, layerA.crs())

        featB = QgsFeature()
        outFeat = QgsFeature()

        indexA = vector.spatialindex(layerB)
        indexB = vector.spatialindex(layerA)

        featuresA = vector.features(layerA)
        featuresB = vector.features(layerB)

        total = 100.0 / (len(featuresA) * len(featuresB))
        count = 0

        for featA in featuresA:
            add = True
            geom = QgsGeometry(featA.geometry())
            diffGeom = QgsGeometry(geom)
            attrs = featA.attributes()
            intersects = indexA.intersects(geom.boundingBox())
            for i in intersects:
                layerB.getFeatures(
                    QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
                tmpGeom = QgsGeometry(featB.geometry())
                if diffGeom.intersects(tmpGeom):
                    diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
                    if not diffGeom.isGeosValid():
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            self.tr('GEOS geoprocessing error: One or '
                                    'more input features have invalid '
                                    'geometry.'))
                        add = False
                        break

            if add:
                try:
                    outFeat.setGeometry(diffGeom)
                    outFeat.setAttributes(attrs)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_WARNING,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
                    continue

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

        length = len(layerA.fields())

        for featA in featuresB:
            add = True
            geom = QgsGeometry(featA.geometry())
            diffGeom = QgsGeometry(geom)
            attrs = featA.attributes()
            attrs = [NULL] * length + attrs
            intersects = indexB.intersects(geom.boundingBox())
            for i in intersects:
                layerA.getFeatures(
                    QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
                tmpGeom = QgsGeometry(featB.geometry())
                if diffGeom.intersects(tmpGeom):
                    diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
                    if not diffGeom.isGeosValid():
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            self.tr('GEOS geoprocessing error: One or '
                                    'more input features have invalid '
                                    'geometry.'))
                        add = False
                        break

            if add:
                try:
                    outFeat.setGeometry(diffGeom)
                    outFeat.setAttributes(attrs)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_WARNING,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
                    continue

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

        del writer
Ejemplo n.º 39
0
    def __project_loaded(self):
        """
        Get saved settings on load
        """

        """ Reference point layers for drawdown tool """
        str_ids = QgsProject.instance().readEntry("VDLTools", "ref_layers", "None")[0]
        ref_ids = str_ids.split(',')

        """ Adjustable point layers for drawdown tool """
        str_ids = QgsProject.instance().readEntry("VDLTools", "adj_layers", "None")[0]
        adj_ids = str_ids.split(',')

        """ Level attribute for drawdown tool """
        self.__levelAtt = QgsProject.instance().readEntry("VDLTools", "level_att", "None")[0]

        """ Level value for drawdown tool """
        value = QgsProject.instance().readEntry("VDLTools", "level_val", "None")[0]
        self.__levelVals = value.split(",")

        """ Drawdown line layer """
        dd_id = QgsProject.instance().readEntry("VDLTools", "drawdown_layer", "None")[0]

        """ Pipe diameter attribute for drawdown line layer """
        self.__pipeDiam = QgsProject.instance().readEntry("VDLTools", "pipe_diam", "None")[0]

        """ Url used to get mnt values on a line """
        self.__mntUrl = QgsProject.instance().readEntry("VDLTools", "mnt_url", "None")[0]

        """ Config table in Database for importing new Lausanne data """
        self.__configTable = QgsProject.instance().readEntry("VDLTools", "config_table", None)[0]

        """ Database used for importing new Lausanne data """
        dbName = QgsProject.instance().readEntry("VDLTools", "db_name", None)[0]

        """ Table in Database containing control values for importing new Lausanne data """
        ctlDbName = QgsProject.instance().readEntry("VDLTools", "ctl_db_name", None)[0]

        """ Schema of the Database used for importing new Lausanne data """
        self.__schemaDb = QgsProject.instance().readEntry("VDLTools", "schema_db", None)[0]

        """ Temporarly points layer for the project """
        mpl_id = QgsProject.instance().readEntry("VDLTools", "memory_points_layer", None)[0]

        """ Temporarly lines layer for the project """
        mll_id = QgsProject.instance().readEntry("VDLTools", "memory_lines_layer", None)[0]

        for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()):
            if layer and layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() == "memory":
                    if layer.geometryType() == QGis.Point:
                        if layer.id() == mpl_id:
                            self.__memoryPointsLayer = layer
                    if layer.geometryType() == QGis.Line:
                        if layer.id() == mll_id:
                            self.__memoryLinesLayer = layer
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:
                        if layer.id() == dd_id:
                            self.__drawdownLayer = layer
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ:
                        if layer.id() in ref_ids:
                            self.__refLayers.append(layer)
                        if layer.id() in adj_ids:
                            self.__adjLayers.append(layer)

        if dbName != "":
            usedDbs = DBConnector.getUsedDatabases()
            if dbName in list(usedDbs.keys()):
                self.__uriDb = usedDbs[dbName]
        if ctlDbName != "":
            usedDbs = DBConnector.getUsedDatabases()
            if ctlDbName in list(usedDbs.keys()):
                self.__ctlDb = usedDbs[ctlDbName]

        self.changedSignal.emit()
Ejemplo n.º 40
0
    def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, ctllDb, configTable, uriDb, schemaDb, mntUrl,
                 refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer, pipeDiam, moreTools):
        """
        Constructor
        :param iface: interface
        :param memoryPointsLayer: working memory points layer
        :param memoryLinesLayer: working memory lines layer
        :param configTable: config table selected for import
        """
        QDialog.__init__(self)
        self.__iface = iface
        self.__memoryPointsLayer = memoryPointsLayer
        self.__memoryLinesLayer = memoryLinesLayer
        self.__ctlDb = ctllDb
        self.__configTable = configTable
        self.__uriDb = uriDb
        self.__schemaDb = schemaDb
        self.__mntUrl = mntUrl
        self.__refLayers = refLayers
        self.__adjLayers = adjLayers
        self.__levelAtt = levelAtt
        self.__levelVal = levelVal
        self.__drawdowmLayer = drawdowmLayer
        self.__pipeDiam = pipeDiam
        self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings"))
        self.__pointsLayers = []
        self.__linesLayers = []
        self.__refAvailableLayers = []
        self.__drawdownLayers = []
        self.__tables = []
        self.__schemas = []
        self.__pipeDiamFields = []
        self.__levelAttFields = []
        self.__dbs = DBConnector.getUsedDatabases()

        self.__refLabels = []
        self.__refChecks = []
        self.__adjChecks = []

        for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()):
            if layer is not None and layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() == "memory":
                    if layer.geometryType() == QGis.Point:
                        self.__pointsLayers.append(layer)
                    if layer.geometryType() == QGis.Line:
                        self.__linesLayers.append(layer)
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ:
                    self.__drawdownLayers.append(layer)
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ:
                    self.__refAvailableLayers.append(layer)

       # self.resize(450, 400)
        self.__layout = QGridLayout()

        line = 0

        intersectLabel = QLabel(QCoreApplication.translate("VDLTools", "Intersect "))
        self.__layout.addWidget(intersectLabel, line, 0)

        line += 1

        pointLabel = QLabel(QCoreApplication.translate("VDLTools", "Working points layer : "))
        self.__layout.addWidget(pointLabel, line, 1)

        self.__pointCombo = QComboBox()
        self.__pointCombo.setMinimumHeight(20)
        self.__pointCombo.setMinimumWidth(50)
        self.__pointCombo.addItem("")
        for layer in self.__pointsLayers:
            self.__pointCombo.addItem(layer.name())
        self.__layout.addWidget(self.__pointCombo, line, 2)
        self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged)
        if self.__memoryPointsLayer is not None:
            if self.__memoryPointsLayer in self.__pointsLayers:
                self.__pointCombo.setCurrentIndex(self.__pointsLayers.index(self.__memoryPointsLayer)+1)

        line += 1

        lineLabel = QLabel(QCoreApplication.translate("VDLTools", "Working lines layer : "))
        self.__layout.addWidget(lineLabel, line, 1)

        self.__lineCombo = QComboBox()
        self.__lineCombo.setMinimumHeight(20)
        self.__lineCombo.setMinimumWidth(50)
        self.__lineCombo.addItem("")
        for layer in self.__linesLayers:
            self.__lineCombo.addItem(layer.name())
        self.__layout.addWidget(self.__lineCombo, line, 2)
        self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged)
        if self.__memoryLinesLayer is not None:
            if self.__memoryLinesLayer in self.__linesLayers:
                self.__lineCombo.setCurrentIndex(self.__linesLayers.index(self.__memoryLinesLayer)+1)

        line += 1

        profilesLabel = QLabel(QCoreApplication.translate("VDLTools", "Profiles "))
        self.__layout.addWidget(profilesLabel, line, 0)

        line += 1

        mntLabel = QLabel(QCoreApplication.translate("VDLTools", "Url for MNT : "))
        self.__layout.addWidget(mntLabel, line, 1)

        self.__mntText = QLineEdit()
        if self.__mntUrl is None or self.__mntUrl == "None":
            self.__mntText.insert('https://map.lausanne.ch/prod/wsgi/profile.json')
        else:
            self.__mntText.insert(self.__mntUrl)
        self.__mntText.setMinimumHeight(20)
        self.__mntText.setMinimumWidth(100)
        self.__layout.addWidget(self.__mntText, line, 2)

        line += 1

        ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown "))
        self.__layout.addWidget(ddLabel, line, 0)

        line += 1

        self.__layout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1)

        namesLayout = QHBoxLayout()
        namesWidget = QWidget()
        namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Reference")))
        namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Adjustable")))
        namesLayout.setContentsMargins(0,0,0,0)
        namesWidget.setLayout(namesLayout)
        self.__layout.addWidget(namesWidget, line, 2)

        line += 1

        for layer in self.__refAvailableLayers:
            refLabel = QLabel("  - " + layer.name())
            self.__refLabels.append(refLabel)
            self.__layout.addWidget(refLabel, line, 1)

            checksLayout = QHBoxLayout()
            checksLayout.setContentsMargins(0,0,0,0)
            checksWidget = QWidget()

            refCheck = QCheckBox()
            self.__refChecks.append(refCheck)
            refCheck.stateChanged.connect(self.__refBoxesChanged)
            checksLayout.addWidget(refCheck)

            adjCheck = QCheckBox()
            self.__adjChecks.append(adjCheck)
            checksLayout.addWidget(adjCheck)

            checksWidget.setLayout(checksLayout)
            self.__layout.addWidget(checksWidget, line, 2)

            line += 1

        levelAttLabel = QLabel(QCoreApplication.translate("VDLTools", "Code(s) on pipe : "))
        self.__layout.addWidget(levelAttLabel, line, 1)

        self.__levelAttCombo = QComboBox()
        self.__levelAttCombo.setMinimumHeight(20)
        self.__levelAttCombo.setMinimumWidth(50)
        self.__levelAttCombo.addItem("")
        self.__layout.addWidget(self.__levelAttCombo, line, 2)

        self.__levelAttCombo.currentIndexChanged.connect(self.__levelAttComboChanged)

        i = 0
        for layer in self.__refAvailableLayers:
            if layer in self.__refLayers:
                self.__refChecks[i].setChecked(True)
            if layer in self.__adjLayers:
                self.__adjChecks[i].setChecked(True)
            i += 1

        line += 1

        levelValLabel = QLabel(QCoreApplication.translate("VDLTools", "Point code attribute : "))
        self.__layout.addWidget(levelValLabel, line, 1)

        self.__levelValText = QLineEdit()
        if self.__levelVal is not None and self.__levelVal != "None":
            self.__levelValText.insert(self.__levelVal)
        self.__levelValText.setMinimumHeight(20)
        self.__levelValText.setMinimumWidth(100)
        self.__layout.addWidget(self.__levelValText, line, 2)

        line += 1

        drawdownLabel = QLabel(QCoreApplication.translate("VDLTools", "drawdown layer : "))
        self.__layout.addWidget(drawdownLabel, line, 1)

        self.__drawdownCombo = QComboBox()
        self.__drawdownCombo.setMinimumHeight(20)
        self.__drawdownCombo.setMinimumWidth(50)
        self.__drawdownCombo.addItem("")
        for layer in self.__drawdownLayers:
            self.__drawdownCombo.addItem(layer.name())
        self.__layout.addWidget(self.__drawdownCombo, line, 2)

        line += 1

        pipeDiamLabel = QLabel(QCoreApplication.translate("VDLTools", "Pipe diameter attribute [cm] : "))
        self.__layout.addWidget(pipeDiamLabel, line, 1)

        self.__pipeDiamCombo = QComboBox()
        self.__pipeDiamCombo.setMinimumHeight(20)
        self.__pipeDiamCombo.setMinimumWidth(50)
        self.__pipeDiamCombo.addItem("")
        self.__layout.addWidget(self.__pipeDiamCombo, line, 2)

        self.__drawdownCombo.currentIndexChanged.connect(self.__drawdownComboChanged)
        self.__pipeDiamCombo.currentIndexChanged.connect(self.__pipeDiamComboChanged)

        if self.__drawdowmLayer is not None:
            if self.__drawdowmLayer in self.__drawdownLayers:
                self.__drawdownCombo.setCurrentIndex(self.__drawdownLayers.index(self.__drawdowmLayer)+1)

        if moreTools:
            line += 1

            importLabel = QLabel(QCoreApplication.translate("VDLTools", "Import "))
            self.__layout.addWidget(importLabel, line, 0)

            line += 1

            dbLabel = QLabel(QCoreApplication.translate("VDLTools", "Import database : "))
            self.__layout.addWidget(dbLabel, line, 1)

            self.__dbCombo = QComboBox()
            self.__dbCombo.setMinimumHeight(20)
            self.__dbCombo.setMinimumWidth(50)
            self.__dbCombo.addItem("")
            for db in list(self.__dbs.keys()):
                self.__dbCombo.addItem(db)
            self.__layout.addWidget(self.__dbCombo, line, 2)

            line += 1

            schemaLabel = QLabel(QCoreApplication.translate("VDLTools", "Database schema : "))
            self.__layout.addWidget(schemaLabel, line, 1)

            self.__schemaCombo = QComboBox()
            self.__schemaCombo.setMinimumHeight(20)
            self.__schemaCombo.setMinimumWidth(50)
            self.__schemaCombo.addItem("")
            self.__layout.addWidget(self.__schemaCombo, line, 2)

            line += 1

            tableLabel = QLabel(QCoreApplication.translate("VDLTools", "Config table : "))
            self.__layout.addWidget(tableLabel, line, 1)

            self.__tableCombo = QComboBox()
            self.__tableCombo.setMinimumHeight(20)
            self.__tableCombo.setMinimumWidth(50)
            self.__tableCombo.addItem("")
            self.__layout.addWidget(self.__tableCombo, line, 2)

            line += 1

            controlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control "))
            self.__layout.addWidget(controlLabel, line, 0)

            line += 1

            ctlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control database : "))
            self.__layout.addWidget(ctlLabel, line, 1)

            self.__ctlCombo = QComboBox()
            self.__ctlCombo.setMinimumHeight(20)
            self.__ctlCombo.setMinimumWidth(50)
            self.__ctlCombo.addItem("")
            for db in list(self.__dbs.keys()):
                self.__ctlCombo.addItem(db)
            self.__layout.addWidget(self.__ctlCombo, line, 2)

            self.__dbCombo.currentIndexChanged.connect(self.__dbComboChanged)
            self.__schemaCombo.currentIndexChanged.connect(self.__schemaComboChanged)
            self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged)

            self.__ctlCombo.currentIndexChanged.connect(self.__ctlComboChanged)

            if self.__uriDb is not None:
                if self.__uriDb.database() in list(self.__dbs.keys()):
                    self.__dbCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__uriDb.database()) + 1)

            if self.__ctlDb is not None:
                if self.__ctlDb.database() in list(self.__dbs.keys()):
                    self.__ctlCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__ctlDb.database()) + 1)
        else:
            self.__dbCombo = None
            self.__schemaCombo = None
            self.__tableCombo = None
            self.__ctlCombo = None

        self.__okButton = QPushButton(QCoreApplication.translate("VDLTools", "OK"))
        self.__okButton.setMinimumHeight(20)
        self.__okButton.setMinimumWidth(100)

        self.__cancelButton = QPushButton(QCoreApplication.translate("VDLTools", "Cancel"))
        self.__cancelButton.setMinimumHeight(20)
        self.__cancelButton.setMinimumWidth(100)

        self.__layout.addWidget(self.__okButton, 100, 1)
        self.__layout.addWidget(self.__cancelButton, 100, 2)
        self.setLayout(self.__layout)
Ejemplo n.º 41
0
    def processAlgorithm(self, progress):
        vlayerA = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        vlayerB = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT2))
        ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL)

        geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(vlayerA.wkbType()))
        fields = vector.combineVectorFields(vlayerA, vlayerB)
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields,
                                                                     geomType, vlayerA.crs())
        outFeat = QgsFeature()
        index = vector.spatialindex(vlayerB)
        selectionA = vector.features(vlayerA)
        total = 100.0 / len(selectionA) if len(selectionA) > 0 else 1
        for current, inFeatA in enumerate(selectionA):
            progress.setPercentage(int(current * total))
            geom = inFeatA.geometry()
            if not geom:
                if ignoreNull:
                    continue
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Input layer A contains NULL geometries. '
                                'Please check "Ignore NULL geometries" '
                                'if you want to run this algorithm anyway.'))
            if not geom.isGeosValid():
                raise GeoAlgorithmExecutionException(
                    self.tr('Input layer A contains invalid geometries '
                            '(feature {}). Unable to complete intersection '
                            'algorithm.'.format(inFeatA.id())))
            atMapA = inFeatA.attributes()
            intersects = index.intersects(geom.boundingBox())
            for inFeatB in vlayerB.getFeatures(QgsFeatureRequest().setFilterFids(intersects)):
                tmpGeom = QgsGeometry(inFeatB.geometry())
                if not geom:
                    if ignoreNull:
                        continue
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Input layer B contains NULL geometries. '
                                    'Please check "Ignore NULL geometries" '
                                    'if you want to run this algorithm anyway.'))
                if not geom.isGeosValid():
                    raise GeoAlgorithmExecutionException(
                        self.tr('Input layer B contains invalid geometries '
                                '(feature {}). Unable to complete intersection '
                                'algorithm.'.format(inFeatB.id())))

                if geom.intersects(tmpGeom):
                    atMapB = inFeatB.attributes()
                    int_geom = QgsGeometry(geom.intersection(tmpGeom))
                    if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
                        int_com = geom.combine(tmpGeom)
                        int_geom = QgsGeometry()
                        if int_com is not None:
                            int_sym = geom.symDifference(tmpGeom)
                            if int_sym:
                                diff_geom = int_com.difference(int_sym)
                                int_geom = QgsGeometry(diff_geom)

                    if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
                        raise GeoAlgorithmExecutionException(
                            self.tr('GEOS geoprocessing error: One or '
                                    'more input features have invalid '
                                    'geometry.'))
                    try:
                        if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]:
                            outFeat.setGeometry(int_geom)
                            attrs = []
                            attrs.extend(atMapA)
                            attrs.extend(atMapB)
                            outFeat.setAttributes(attrs)
                            writer.addFeature(outFeat)
                    except:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Feature geometry error: one or '
                                    'more output features ignored due '
                                    'to invalid geometry.'))

        del writer
Ejemplo n.º 42
0
 def spatial_unit(self):
     u = self.rgis.crs.mapUnits()
     su = QGis.toLiteral(u).upper()
     return su
Ejemplo n.º 43
0
    def addAnyFeature(self, featureType, mapPointList, attributes, layer):
        geometryType = FeatureType.toGeometryType(featureType)

        # points: bail out if there is not exactly one vertex
        if (geometryType == QGis.Point and len(mapPointList) != 1):
            return False

        # segments: bail out if there are not exactly two vertices
        if (featureType == FeatureType.Segment and len(mapPointList) != 2):
            return False

        # lines: bail out if there are not at least two vertices
        if (featureType == FeatureType.Line and len(mapPointList) < 2):
            return False

        # polygons: bail out if there are not at least three vertices
        if (geometryType == QGis.Polygon and len(mapPointList) < 3):
            return False

        if (geometryType != layer.geometryType()):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Layer and Feature geometry type mismatch'), QgsMessageBar.CRITICAL)
            return False

        if (layer.type() != QgsMapLayer.VectorLayer):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Current layer not a vector layer'), QgsMessageBar.CRITICAL)
            return False

        if (not layer.isEditable()):
            self.messageEmitted.emit(self.tr('Cannot add feature: Current layer not editable'), QgsMessageBar.CRITICAL)
            return False

        provider = layer.dataProvider()
        if (not (provider.capabilities() & QgsVectorDataProvider.AddFeatures)):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Data provider does not support the addition of features.'),
                QgsMessageBar.CRITICAL)
            return False

        multiType = QGis.isMultiType(layer.wkbType())
        layerPoints = self._layerPoints(mapPointList, layer)
        feature = QgsFeature(layer.pendingFields(), 0)
        geometry = None

        if (geometryType == QGis.Point):
            if multiType:
                geometry = QgsGeometry.fromMultiPoint([layerPoints[0]])
            else:
                geometry = QgsGeometry(layerPoints[0])
        elif (geometryType == QGis.Line):
            if multiType:
                geometry = QgsGeometry.fromMultiPolyline([layerPoints])
            else:
                geometry = QgsGeometry.fromPolyline(layerPoints)
        elif (geometryType == QGis.Polygon):
            if multiType:
                geometry = QgsGeometry.fromMultiPolygon([layerPoints])
            else:
                geometry = QgsGeometry.fromPolygon([layerPoints])
        else:
            self.messageEmitted.emit(self.tr('Cannot add feature. Unknown geometry type'), QgsMessageBar.CRITICAL)
            return False

        if (geometry is None):
            self.messageEmitted.emit(self.tr('Cannot add feature. Invalid geometry'), QgsMessageBar.CRITICAL)
            return False
        feature.setGeometry(geometry)

        if (geometryType == QGis.Polygon):

            avoidIntersectionsReturn = feature.geometry().avoidIntersections()
            if (avoidIntersectionsReturn == 1):
                # not a polygon type. Impossible to get there
                pass
            elif (avoidIntersectionsReturn == 3):
                self.messageEmitted.emit(
                    self.tr('An error was reported during intersection removal'), QgsMessageBar.CRITICAL)

            if (not feature.geometry().asWkb()):  # avoid intersection might have removed the whole geometry
                reason = ''
                if (avoidIntersectionsReturn != 2):
                    reason = self.tr('The feature cannot be added because it\'s geometry is empty')
                else:
                    reason = self.tr(
                        'The feature cannot be added because it\'s geometry collapsed due to intersection avoidance')
                self.messageEmitted.emit(reason, QgsMessageBar.CRITICAL)
                return False

        featureSaved = self._addFeatureAction(feature, attributes, layer, False)

        if (featureSaved and geometryType != QGis.Point):
            # add points to other features to keep topology up-to-date
            topologicalEditing = Snapping.topologicalEditing()

            # use always topological editing for avoidIntersection.
            # Otherwise, no way to guarantee the geometries don't have a small gap in between.
            intersectionLayers = Snapping.intersectionLayers()
            avoidIntersection = len(intersectionLayers)
            if (avoidIntersection):  # try to add topological points also to background layers
                for intersectionLayer in intersectionLayers:
                    vl = QgsMapLayerRegistry.instance().mapLayer(str(intersectionLayer))
                    # can only add topological points if background layer is editable...
                    if (vl is not None and vl.geometryType() == QGis.Polygon and vl.isEditable()):
                        vl.addTopologicalPoints(feature.geometry())
            elif (topologicalEditing):
                self._layer.addTopologicalPoints(feature.geometry())

        self.canvas().refresh()

        return True
Ejemplo n.º 44
0
    def __project_loaded(self):
        """
        Get saved settings on load
        """
        """ Reference point layers for drawdown tool """
        str_ids = QgsProject.instance().readEntry("VDLTools", "ref_layers",
                                                  "None")[0]
        ref_ids = str_ids.split(',')
        """ Adjustable point layers for drawdown tool """
        str_ids = QgsProject.instance().readEntry("VDLTools", "adj_layers",
                                                  "None")[0]
        adj_ids = str_ids.split(',')
        """ Level attribute for drawdown tool """
        self.__levelAtt = QgsProject.instance().readEntry(
            "VDLTools", "level_att", "None")[0]
        """ Level value for drawdown tool """
        value = QgsProject.instance().readEntry("VDLTools", "level_val",
                                                "None")[0]
        self.__levelVals = value.split(",")
        """ Drawdown line layer """
        dd_id = QgsProject.instance().readEntry("VDLTools", "drawdown_layer",
                                                "None")[0]
        """ Pipe diameter attribute for drawdown line layer """
        self.__pipeDiam = QgsProject.instance().readEntry(
            "VDLTools", "pipe_diam", "None")[0]
        """ Url used to get mnt values on a line """
        self.__mntUrl = QgsProject.instance().readEntry(
            "VDLTools", "mnt_url", "None")[0]
        """ Config table in Database for importing new Lausanne data """
        self.__importConfigTable = QgsProject.instance().readEntry(
            "VDLTools", "import_config_table", None)[0]
        """ Config table in Database for controling """
        self.__controlConfigTable = QgsProject.instance().readEntry(
            "VDLTools", "control_config_table", None)[0]
        """ Database used for importing new Lausanne data """
        importDbName = QgsProject.instance().readEntry("VDLTools",
                                                       "import_db_name",
                                                       None)[0]
        """ Database used for controling """
        controlDbName = QgsProject.instance().readEntry(
            "VDLTools", "control_db_name", None)[0]
        """ Schema of the Database used for importing new Lausanne data """
        self.__importSchemaDb = QgsProject.instance().readEntry(
            "VDLTools", "import_schema_db", None)[0]
        """ Schema of the Database used for controling """
        self.__controlSchemaDb = QgsProject.instance().readEntry(
            "VDLTools", "control_schema_db", None)[0]
        """ Temporarly points layer for the project """
        mpl_id = QgsProject.instance().readEntry("VDLTools",
                                                 "memory_points_layer",
                                                 None)[0]
        """ Temporarly lines layer for the project """
        mll_id = QgsProject.instance().readEntry("VDLTools",
                                                 "memory_lines_layer", None)[0]

        for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()):
            if layer and layer.type() == QgsMapLayer.VectorLayer:
                if layer.providerType() == "memory":
                    if layer.geometryType() == QGis.Point:
                        if layer.id() == mpl_id:
                            self.__memoryPointsLayer = layer
                    if layer.geometryType() == QGis.Line:
                        if layer.id() == mll_id:
                            self.__memoryLinesLayer = layer
                if QGis.fromOldWkbType(
                        layer.wkbType()) == QgsWKBTypes.LineStringZ:
                    if layer.id() == dd_id:
                        self.__drawdownLayer = layer
                if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ:
                    if layer.id() in ref_ids:
                        self.__refLayers.append(layer)
                    if layer.id() in adj_ids:
                        self.__adjLayers.append(layer)

        if importDbName != "" or controlDbName != "":
            usedDbs = DBConnector.getUsedDatabases()
            if importDbName != "" and importDbName in list(usedDbs.keys()):
                self.__importUriDb = usedDbs[importDbName]
            if controlDbName != "" and controlDbName in list(usedDbs.keys()):
                self.__controlUriDb = usedDbs[controlDbName]

        self.changedSignal.emit()
Ejemplo n.º 45
0
    def processAlgorithm(self, progress):
        vlayerA = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        vlayerB = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT2))
        ignoreNull = self.getParameterValue(Intersection.IGNORE_NULL)

        geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(
            vlayerA.wkbType()))
        fields = vector.combineVectorFields(vlayerA, vlayerB)
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, geomType, vlayerA.crs())
        outFeat = QgsFeature()
        index = vector.spatialindex(vlayerB)
        selectionA = vector.features(vlayerA)
        total = 100.0 / len(selectionA)
        for current, inFeatA in enumerate(selectionA):
            progress.setPercentage(int(current * total))
            geom = inFeatA.geometry()
            if not geom:
                if ignoreNull:
                    continue
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Input layer A contains NULL geometries. '
                                'Please check "Ignore NULL geometries" '
                                'if you want to run this algorithm anyway.'))
            if not geom.isGeosValid():
                raise GeoAlgorithmExecutionException(
                    self.tr('Input layer A contains invalid geometries '
                            '(feature {}). Unable to complete intersection '
                            'algorithm.'.format(inFeatA.id())))
            atMapA = inFeatA.attributes()
            intersects = index.intersects(geom.boundingBox())
            for inFeatB in vlayerB.getFeatures(
                    QgsFeatureRequest().setFilterFids(intersects)):
                tmpGeom = QgsGeometry(inFeatB.geometry())
                if not geom:
                    if ignoreNull:
                        continue
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.tr(
                                'Input layer B contains NULL geometries. '
                                'Please check "Ignore NULL geometries" '
                                'if you want to run this algorithm anyway.'))
                if not geom.isGeosValid():
                    raise GeoAlgorithmExecutionException(
                        self.tr(
                            'Input layer B contains invalid geometries '
                            '(feature {}). Unable to complete intersection '
                            'algorithm.'.format(inFeatB.id())))

                if geom.intersects(tmpGeom):
                    atMapB = inFeatB.attributes()
                    int_geom = QgsGeometry(geom.intersection(tmpGeom))
                    if int_geom.wkbType(
                    ) == QGis.WKBUnknown or QgsWKBTypes.flatType(
                            int_geom.geometry().wkbType(
                            )) == QgsWKBTypes.GeometryCollection:
                        int_com = geom.combine(tmpGeom)
                        int_geom = QgsGeometry()
                        if int_com is not None:
                            int_sym = geom.symDifference(tmpGeom)
                            if int_sym:
                                diff_geom = int_com.difference(int_sym)
                                int_geom = QgsGeometry(diff_geom)

                    if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
                        raise GeoAlgorithmExecutionException(
                            self.tr('GEOS geoprocessing error: One or '
                                    'more input features have invalid '
                                    'geometry.'))
                    try:
                        if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[
                                int_geom.wkbType()]]:
                            outFeat.setGeometry(int_geom)
                            attrs = []
                            attrs.extend(atMapA)
                            attrs.extend(atMapB)
                            outFeat.setAttributes(attrs)
                            writer.addFeature(outFeat)
                    except:
                        raise GeoAlgorithmExecutionException(
                            self.tr('Feature geometry error: one or '
                                    'more output features ignored due '
                                    'to invalid geometry.'))

        del writer
Ejemplo n.º 46
0
    def spatialInfo(self):
        ret = []
        if not self.table.geomType:
            return ret

        tbl = [
            (QApplication.translate("DBManagerPlugin", "Column:"),
             self.table.geomColumn),
            (QApplication.translate("DBManagerPlugin", "Geometry:"),
             self.table.geomType),
            (QApplication.translate("DBManagerPlugin",
                                    "QGis Geometry type:"),
             QGis.featureType(self.table.wkbType))
        ]

        # only if we have info from geometry_columns
        if self.table.geomDim:
            tbl.append(
                (QApplication.translate(
                    "DBManagerPlugin",
                    "Dimension:"),
                 self.table.geomDim))

        srid = self.table.srid if self.table.srid else -1
        if srid != -1:
            sr_info = (
                self.table.database().connector.getSpatialRefInfo(srid))
        else:
            sr_info = QApplication.translate("DBManagerPlugin",
                                             "Undefined")
        if sr_info:
            tbl.append(
                (QApplication.translate(
                    "DBManagerPlugin", "Spatial ref:"),
                 u"{0} ({1})".format(sr_info, srid)))

        # estimated extent
        if not self.table.estimatedExtent:
            # estimated extent information is not displayed yet, so just block
            # table signals to avoid double refreshing
            # (infoViewer->refreshEstimatedExtent->tableChanged->infoViewer)
            self.table.blockSignals(True)
            self.table.refreshTableEstimatedExtent()
            self.table.blockSignals(False)

        if self.table.estimatedExtent:
            estimated_extent_str = (u"{:.9f}, {:.9f} - {:.9f}, "
                                    u"{:.9f}".format(
                                        *self.table.estimatedExtent))

            tbl.append(
                (QApplication.translate(
                    "DBManagerPlugin", "Estimated extent:"),
                 estimated_extent_str))

        # extent
        extent_str = None
        if self.table.extent and len(self.table.extent) == 4:
            extent_str = (u"{:.9f}, {:.9f} - {:.9f}, "
                          u"{:.9f}".format(*self.table.extent))
        elif self.table.rowCount > 0 or self.table.estimatedRowCount > 0:
            # Can't calculate an extent on empty layer
            extent_str = QApplication.translate(
                "DBManagerPlugin",
                '(unknown) (<a href="action:extent/get">find out</a>)')

        if extent_str:
            tbl.append(
                (QApplication.translate(
                    "DBManagerPlugin", "Extent:"),
                 extent_str))

        ret.append(HtmlTable(tbl))

        # Handle extent update metadata
        if (self.table.extent
                and self.table.extent != self.table.estimatedExtent
                and self.table.canUpdateMetadata()):
            ret.append(
                HtmlParagraph(
                    QApplication.translate(
                        "DBManagerPlugin",
                        (u'<warning> Metadata extent is different from'
                         u'real extent. You should <a href="action:extent'
                         u'/update">update it</a>!'))))

        # is there an entry in geometry_columns?
        if self.table.geomType.lower() == 'geometry':
            ret.append(
                HtmlParagraph(
                    QApplication.translate(
                        "DBManagerPlugin",
                        "<warning> There is no entry in geometry_columns!")))

        # find out whether the geometry column has spatial index on it
        if not self.table.isView:
            if not self.table.hasSpatialIndex():
                ret.append(
                    HtmlParagraph(
                        QApplication.translate(
                            "DBManagerPlugin",
                            (u'<warning> No spatial index defined (<a href='
                             u'"action:spatialindex/create">'
                             u'create it</a>).'))))

        return ret
Ejemplo n.º 47
0
def to_feature_data(layerid, feature, renderer, transform):
    """
    Transform the feature into the data for the viewer to use.
    :param feature: QgsFeature
    :param renderer:
    :param transform:
    :return:
    """

    def polylinenodes(polyline):
        nodes = []
        for point in polyline:
            point = transform.transform(point, QgsCoordinateTransform.ReverseTransform)
            location = dict(lat=point.y(), lng=point.x())
            nodes.append(location)
        return nodes

    geom = feature.geometry()
    geomtype = geom.type()
    featuredata = []
    data = dict(
        id=feature.id(), layerid=layerid, color=get_color(renderer, feature), geomtype=QGis.vectorGeometryType(geomtype)
    )
    if geomtype == QGis.Point:
        geom = geom.asPoint()
        point = transform.transform(geom, QgsCoordinateTransform.ReverseTransform)
        try:
            z = feature["Z"]
            if not z:
                z = 0
        except KeyError:
            z = 0
        location = dict(lat=point.y(), lng=point.x(), z=z)
        data["nodes"] = [location]
        featuredata.append(data)
    elif geomtype == QGis.Line:
        if geom.isMultipart():
            # Copy the data for each polyline
            for polyline in geom.asMultiPolyline():
                newdata = copy.copy(data)
                newdata["nodes"] = polylinenodes(polyline)
                featuredata.append(newdata)
        else:
            data["nodes"] = polylinenodes(geom.asPolyline())
            featuredata.append(data)
    return featuredata
Ejemplo n.º 48
0
 def spatial_unit(self):
     u = self.rgis.crs.mapUnits()
     su = QGis.toLiteral(u).upper()
     return su
Ejemplo n.º 49
0
    def processAlgorithm(self, progress):
        layerA = dataobjects.getObjectFromUri(
            self.getParameterValue(Difference.INPUT))
        layerB = dataobjects.getObjectFromUri(
            self.getParameterValue(Difference.OVERLAY))
        ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID)

        geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType()))
        writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter(
            layerA.pendingFields(), geomType, layerA.crs())

        outFeat = QgsFeature()
        index = vector.spatialindex(layerB)
        selectionA = vector.features(layerA)
        total = 100.0 / len(selectionA)
        for current, inFeatA in enumerate(selectionA):
            add = True
            geom = QgsGeometry(inFeatA.geometry())
            diff_geom = QgsGeometry(geom)
            attrs = inFeatA.attributes()
            intersections = index.intersects(geom.boundingBox())
            for i in intersections:
                request = QgsFeatureRequest().setFilterFid(i)
                inFeatB = layerB.getFeatures(request).next()
                tmpGeom = QgsGeometry(inFeatB.geometry())
                if diff_geom.intersects(tmpGeom):
                    diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
                    if diff_geom.isGeosEmpty():
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_INFO,
                            self.tr('Feature with NULL geometry found.'))
                    if not diff_geom.isGeosValid():
                        if ignoreInvalid:
                            ProcessingLog.addToLog(
                                ProcessingLog.LOG_ERROR,
                                self.
                                tr('GEOS geoprocessing error: One or more input features have invalid geometry.'
                                   ))
                            add = False
                        else:
                            raise GeoAlgorithmExecutionException(
                                self.
                                tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag'
                                   ))
                        break

            if add:
                try:
                    outFeat.setGeometry(diff_geom)
                    outFeat.setAttributes(attrs)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_WARNING,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
                    continue

            progress.setPercentage(int(current * total))

        del writer
Ejemplo n.º 50
0
    def processEllipse(self, layer, outname, semimajorcol, semiminorcol,
                       orientcol, unitOfMeasure, defSemiMajor, defSemiMinor,
                       defOrientation):
        measureFactor = 1.0
        # The ellipse calculation is done in Nautical Miles. This converts
        # the semi-major and minor axis to nautical miles
        if unitOfMeasure == 2:  # Nautical Miles
            measureFactor = 1.0
        elif unitOfMeasure == 0:  # Kilometers
            measureFactor = QGis.fromUnitToUnitFactor(
                QGis.Meters, QGis.NauticalMiles) * 1000.0
        elif unitOfMeasure == 1:  # Meters
            measureFactor = QGis.fromUnitToUnitFactor(QGis.Meters,
                                                      QGis.NauticalMiles)
        elif unitOfMeasure == 3:  # Miles
            measureFactor = QGis.fromUnitToUnitFactor(
                QGis.Feet, QGis.NauticalMiles) * 5280.0
        elif unitOfMeasure == 4:  # Feet
            measureFactor = QGis.fromUnitToUnitFactor(QGis.Feet,
                                                      QGis.NauticalMiles)

        fields = layer.pendingFields()

        self.polygonLayer = QgsVectorLayer("Polygon?crs=epsg:4326", outname,
                                           "memory")
        ppolygon = self.polygonLayer.dataProvider()
        ppolygon.addAttributes(fields)
        self.polygonLayer.updateFields()

        iter = layer.getFeatures()
        num_features = 0
        num_good = 0
        for feature in iter:
            num_features += 1
            try:
                if semimajorcol != -1:
                    semi_major = float(feature[semimajorcol])
                else:
                    semi_major = defSemiMajor
                if semiminorcol != -1:
                    semi_minor = float(feature[semiminorcol])
                else:
                    semi_minor = defSemiMinor
                if orientcol != -1:
                    orient = float(feature[orientcol])
                else:
                    orient = defOrientation
                pt = feature.geometry().asPoint()
                # make sure the coordinates are in EPSG:4326
                pt = self.transform.transform(pt.x(), pt.y())
                geom = LatLon.getEllipseCoords(pt.y(), pt.x(),
                                               semi_major * measureFactor,
                                               semi_minor * measureFactor,
                                               orient)
                featureout = QgsFeature()
                featureout.setGeometry(QgsGeometry.fromPolygon([geom]))
                featureout.setAttributes(feature.attributes())
                ppolygon.addFeatures([featureout])
                num_good += 1
            except:
                # Just skip any lines that are badly formed
                pass
        self.polygonLayer.updateExtents()
        QgsMapLayerRegistry.instance().addMapLayer(self.polygonLayer)
        self.iface.messageBar().pushMessage(
            "",
            "{} Ellipses created from {} records".format(
                num_good, num_features),
            level=QgsMessageBar.INFO,
            duration=3)