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 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.º 3
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.º 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 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.º 6
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.º 7
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.º 8
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.º 9
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.º 10
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.º 11
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.º 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