Beispiel #1
1
def save2PointShape(shapePath, geodata, attribName,
                    attribData, label, spatialRef):
    """
    :param label:
    :param shapePath: Pfad wo Shapefile agespeichert wird
    :param geodata: Koordinaten der Punkte
    :param attribName: Attributname (Feldname) von zusätzlichen Werten
    :param attribData: Werte für Attribute
    :param spatialRef: Räumliche Referenz
    """

    # define fields for feature attributes. A QgsFields object is needed
    fields = QgsFields()
    fields.append(QgsField("StuetzenNr", QVariant.String))
    fields.append(QgsField(attribName, QVariant.Int))
    writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.PointZ,
                                 spatialRef, "ESRI Shapefile")

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception("Vector Writer")

    for idx, (coords, attrib) in enumerate(zip(geodata, attribData)):
        feature = QgsFeature()
        feature.setFields(fields)
        # TODO: Nicht 3D weil Methode fromPoint() nicht existiert. Wird evtl. in der Zukunft implementiert
        feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(coords[0], coords[1])))
        feature.setId(idx)
        feature.setAttribute("StuetzenNr", label[idx])
        feature.setAttribute(attribName, attrib)
        writer.addFeature(feature)
        del feature

    # delete the writer to flush features to disk
    del writer
Beispiel #2
0
def saveLineGeometry(shapePath, geodata, spatialRef, geoFormat):
    """
    :param shapePath: Location of shape file
    :param geodata: x, y and z coordinate of line
    :param spatialRef: current spatial reference of qgis project
    :param geoFormat: Geodata export format
    """
    # Define fields for feature attributes. A QgsFields object is needed
    fields = QgsFields()
    writer = QgsVectorFileWriter(shapePath, 'UTF-8', fields,
                                 QgsWkbTypes.LineStringZ, spatialRef,
                                 geoFormat)

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception('Vector Writer')

    lineVertices = []
    for coords in geodata:
        lineVertices.append(QgsPoint(coords[0], coords[1], coords[2]))

    feature = QgsFeature()
    feature.setGeometry(QgsGeometry.fromPolyline(lineVertices))
    feature.setId(1)
    writer.addFeatures([feature])
    del feature
    # Delete the writer to flush features to disk
    del writer
    def check_if_export_file_in_use(self):
        """
        Attempts to write to export file, to check if in use. Warns if so.
        This check only works in Windows.
        :return: boolean
        """
        if config.DEBUG_MODE:
            print('DEBUG_MODE: Checking if output file in use.')
        field_map = QgsFields()
        for field in self.fields:
            field_map.append(field)

        writer = QgsVectorFileWriter(str(self.export_path), "utf-8", field_map,
                                     QGis.WKBMultiLineString, None,
                                     "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            file_open_msg_box = QMessageBox(
                QMessageBox.Warning, " ", "The file {} is already open "
                "(possibly in another application).\n"
                "Close the file and try again".format(str(self.export_path)),
                QMessageBox.Ok, None)
            file_open_msg_box.setWindowFlags(Qt.CustomizeWindowHint
                                             | Qt.WindowTitleHint)
            file_open_msg_box.exec_()
            return True
        return False
Beispiel #4
0
def to_shp(path, any_features_list, layer_fields, crs, name, encoding, geom_type):
    if path is None:
        if geom_type == 0:
            network = QgsVectorLayer('Point?crs=' + crs.toWkt(), name, "memory")
        else:
            network = QgsVectorLayer('LineString?crs=' + crs.toWkt(), name, "memory")
    else:
        fields = QgsFields()
        for field in layer_fields:
            fields.append(field)
        file_writer = QgsVectorFileWriter(path, encoding, fields, geom_type, crs, "ESRI Shapefile")
        if file_writer.hasError() != QgsVectorFileWriter.NoError:
            print "Error when creating shapefile: ", file_writer.errorMessage()
        del file_writer
        network = QgsVectorLayer(path, name, "ogr")
    pr = network.dataProvider()
    if path is None:
        pr.addAttributes(layer_fields)
    new_features = []
    for i in any_features_list:
        new_feat = QgsFeature()
        new_feat.setFeatureId(i[0])
        new_feat.setAttributes([attr[0] for attr in i[1]])
        new_feat.setGeometry(QgsGeometry(QgsGeometry.fromWkt(str(i[2]))))
        #QgsGeometry()
        new_features.append(new_feat)
    network.startEditing()
    pr.addFeatures(new_features)
    network.commitChanges()
    return network
Beispiel #5
0
	def fileHanddler(self, alayer, alist, filedirectory, name):
		crsSrc = alayer.crs()
		crsDes = QgsCoordinateReferenceSystem(crsSrc.authid())
		fieldz = QgsFields()
		fieldz.append(QgsField("Id", QVariant.Int))
		fieldz.append(QgsField("Ré", QVariant.String))
		fieldz.append(QgsField("Norte", QVariant.Double, "double", 23, 2))
		fieldz.append(QgsField("Este", QVariant.Double, "double", 23, 2))
		fieldz.append(QgsField("Longitude", QVariant.String))
		fieldz.append(QgsField("Latitude", QVariant.String))
		fieldz.append(QgsField("Vante", QVariant.String))
		fieldz.append(QgsField("Azimute", QVariant.String))
		fieldz.append(QgsField("Distancia", QVariant.Double, "double", 23, 2))

		writer = QgsVectorFileWriter(filedirectory+'/'+name, "UTF-8", fieldz, QgsWkbTypes.Point, crsDes,
			driverName="ESRI Shapefile")

		if writer.hasError() != QgsVectorFileWriter.NoError:
			print("Error when creating shapefile:", writer.errorMessage())

		writer.addFeatures(alist)
		del writer
		nwLayer = self.iface.addVectorLayer(filedirectory+'/'+name, "", "ogr")
		if not nwLayer:
			print("Layer failed to load!")
		return
Beispiel #6
0
def to_shp(path, any_features_list, layer_fields, crs, name, encoding,
           geom_type):
    if path is None:
        if geom_type == 0:
            network = QgsVectorLayer('Point?crs=' + crs.toWkt(), name,
                                     "memory")
        else:
            network = QgsVectorLayer('LineString?crs=' + crs.toWkt(), name,
                                     "memory")
    else:
        fields = QgsFields()
        for field in layer_fields:
            fields.append(field)
        file_writer = QgsVectorFileWriter(path, encoding, fields, geom_type,
                                          crs, "ESRI Shapefile")
        if file_writer.hasError() != QgsVectorFileWriter.NoError:
            print "Error when creating shapefile: ", file_writer.errorMessage()
        del file_writer
        network = QgsVectorLayer(path, name, "ogr")
    pr = network.dataProvider()
    if path is None:
        pr.addAttributes(layer_fields)
    new_features = []
    for i in any_features_list:
        new_feat = QgsFeature()
        new_feat.setFeatureId(i[0])
        new_feat.setAttributes([attr[0] for attr in i[1]])
        new_feat.setGeometry(QgsGeometry(QgsGeometry.fromWkt(str(i[2]))))
        #QgsGeometry()
        new_features.append(new_feat)
    network.startEditing()
    pr.addFeatures(new_features)
    network.commitChanges()
    return network
 def to_shp(self,
            path,
            name,
            crs,
            encoding,
            geom_type,
            features,
            graph='primal'):
     if graph == 'primal':
         flds = self.edge_qflds
     elif graph == 'dual':
         flds = [
             QgsField('source', QVariant.String),
             QgsField('target', QVariant.String),
             QgsField('cost', QVariant.Int)
         ]
     if path is None:
         network = QgsVectorLayer('MultiLineString?crs=' + crs.toWkt(),
                                  name, "memory")
     else:
         file_writer = QgsVectorFileWriter(path, encoding, flds, geom_type,
                                           crs, "ESRI Shapefile")
         if file_writer.hasError() != QgsVectorFileWriter.NoError:
             print "Error when creating shapefile: ", file_writer.errorMessage(
             )
         del file_writer
         network = QgsVectorLayer(path, name, "ogr")
     # QgsMapLayerRegistry.instance().addMapLayer(network)
     pr = network.dataProvider()
     network.startEditing()
     if path is None:
         pr.addAttributes(flds)
     pr.addFeatures(features)
     network.commitChanges()
     return network
Beispiel #8
0
 def create_datasource_from_template(self, datasource):
     fieldSet = QgsFields()
     for fieldDef in FIELDS_TEMPLATE:
         fieldSet.append(self.getFieldFromDefinition(fieldDef))
     writer = QgsVectorFileWriter(datasource, 'UTF-8', fieldSet, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(4326),"ESRI Shapefile")
     if writer.hasError():
         print ("error",writer.errorMessage())
     del writer
Beispiel #9
0
def createShapefile(filePath, name, wkbType, crs, fields, styleURI=None, symbology=None):
    # WARNING This will overwrite existing files
    writer = QgsVectorFileWriter(filePath, 'System', fields, wkbType, crs)
    if writer.hasError():
        utils.debug(writer.errorMessage())
    del writer
    layer = QgsVectorLayer(filePath, name, 'ogr')
    loadStyle(layer, styleURI, symbology)
    return layer
Beispiel #10
0
    def create_reservoirs_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(QgsField(Reservoir.field_name_eid, QVariant.String))
        fields.append(QgsField(Reservoir.field_name_elev, QVariant.Double))
        fields.append(QgsField(Reservoir.field_name_delta_z, QVariant.Double))
        # fields.append(QgsField(Reservoir.field_name_head, QVariant.Double))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QgsWkbTypes.Point, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
Beispiel #11
0
    def create_pumps_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(QgsField(QgsField(Pump.field_name_eid, QVariant.String)))
        # fields.append(QgsField(QgsField(Pump.field_name_from_node, QVariant.String)))
        # fields.append(QgsField(QgsField(Pump.field_name_to_node, QVariant.String)))
        fields.append(
            QgsField(QgsField(Pump.field_name_param, QVariant.String)))
        fields.append(
            QgsField(QgsField(Pump.field_name_value, QVariant.String)))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QGis.WKBLineString, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
Beispiel #12
0
def createEmptyVectorLayer(path,
                           formatDriver,
                           fields=None,
                           srcCrs=QgsCoordinateReferenceSystem(
                               4326, QgsCoordinateReferenceSystem.EpsgCrsId),
                           shape=QgsWkbTypes.Polygon,
                           encoding="UTF-8"):
    """
    Create empty vector layer.
    """
    validDriver = False
    drivers = QgsVectorFileWriter.ogrDriverList()
    for driver in drivers:
        validDriver = driver.longName == formatDriver
    if not formatDriver:
        print("Not applicable formatDriver" + str(drivers))
        return False
    writer = QgsVectorFileWriter(path, encoding, fields, shape, srcCrs,
                                 formatDriver)
    if writer.hasError() != QgsVectorFileWriter.NoError:
        print("Error when creating shapefile: ", writer.hasError())
        del writer
        return False
    return writer
Beispiel #13
0
def createShapefile(filePath,
                    name,
                    wkbType,
                    crs,
                    fields,
                    styleURI=None,
                    symbology=None):
    # WARNING This will overwrite existing files
    writer = QgsVectorFileWriter(filePath, 'System', fields, wkbType, crs)
    if writer.hasError():
        utils.debug(writer.errorMessage())
    del writer
    layer = QgsVectorLayer(filePath, name, 'ogr')
    loadStyle(layer, styleURI, symbology)
    return layer
Beispiel #14
0
def open_shapefile_writer(vlayer, shapefile_path):
    # Prepare inputs
    fields = vlayer.fields()

    # Create writer
    writer = QgsVectorFileWriter(
        shapefile_path, "utf-8", fields, QGis.WKBMultiPolygon,
        QgsCoordinateReferenceSystem(27700,
                                     QgsCoordinateReferenceSystem.EpsgCrsId),
        'ESRI Shapefile')

    if writer.hasError() != QgsVectorFileWriter.NoError:
        msg = "Error when creating shapefile: {}".format(writer.errorMessage())
        raise rn_except.CannotOpenShapefilePopupError(msg)

    return writer
Beispiel #15
0
    def create_junctions_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(
            QgsField(QgsField(Junction.field_name_eid, QVariant.String)))
        fields.append(
            QgsField(QgsField(Junction.field_name_demand, QVariant.Double)))
        fields.append(QgsField(Junction.field_name_elev, QVariant.Double))
        fields.append(QgsField(Junction.field_name_delta_z, QVariant.Double))
        fields.append(QgsField(Junction.field_name_pattern, QVariant.String))
        fields.append(
            QgsField(Junction.field_name_emitter_coeff, QVariant.Double))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QgsWkbTypes.Point, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
Beispiel #16
0
    def create_tanks_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(QgsField(Tank.field_name_eid, QVariant.String))
        fields.append(QgsField(Tank.field_name_curve, QVariant.Int))
        fields.append(QgsField(Tank.field_name_diameter, QVariant.Double))
        fields.append(QgsField(Tank.field_name_elev, QVariant.Double))
        fields.append(QgsField(Tank.field_name_delta_z, QVariant.Double))
        fields.append(QgsField(Tank.field_name_level_init, QVariant.Double))
        fields.append(QgsField(Tank.field_name_level_max, QVariant.Double))
        fields.append(QgsField(Tank.field_name_level_min, QVariant.Double))
        fields.append(QgsField(Tank.field_name_vol_min, QVariant.Double))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QgsWkbTypes.Point, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
    def _createLayer(self, filename, crs, geometries):
        if len(geometries) < 1:
            raise AerogenError(self.tr("No features to write"))
        geom_type = geometries[0].wkbType()

        writer = QgsVectorFileWriter(filename, "UTF-8", QgsFields(),
                                     geom_type, crs, "ESRI Shapefile")

        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise AerogenError(
                'Failed creating Shapefile: {}'.format(writer.errorMessage())
            )

        for geom in geometries:
            fet = QgsFeature()
            fet.setGeometry(geom)
            writer.addFeature(fet)
def create_shplayer_from_template(template, legend=True):
    #print "creating",template['datasource']
    fieldSet = QgsFields()
    for fieldDef in template['fields']:
        fieldSet.append(getFieldFromDefinition(fieldDef))

    writer = QgsVectorFileWriter(template['datasource'], 'UTF-8', fieldSet,
                                 template['geomtype'],
                                 QgsCoordinateReferenceSystem(template['srs']))
    if writer.hasError():
        print writer.errorMessage()
    del writer
    lyr = QgsVectorLayer(template['datasource'], template['name'], 'ogr')
    if template['style']:
        lyr.loadNamedStyle(template['style'])
    if legend:
        QgsMapLayerRegistry.instance().addMapLayer(lyr)
    return lyr
Beispiel #19
0
    def create_valves_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(QgsField(QgsField(Valve.field_name_eid,
                                        QVariant.String)))
        fields.append(
            QgsField(QgsField(Valve.field_name_diameter, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Valve.field_name_minor_loss, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Valve.field_name_setting, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Valve.field_name_type, QVariant.String)))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QGis.WKBLineString, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
Beispiel #20
0
    def _toVectorLayer_geojson (self):        
        crs = QgsCoordinateReferenceSystem()
        crs.createFromUserInput(self.provider.srsName)
        
        fileName = self.xmlFile.replace(".xml", ".geojson")
        fields = QgsFields ()
        map (fields.append, self.provider.fields)
        writer = QgsVectorFileWriter (fileName, "utf-8", fields, QGis.WKBPoint, crs, "GeoJSON")

        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception (writer.errorMessage())
        
        for feature in self.provider.getFeatures():
            self.features.append(feature)
            writer.addFeature(feature)
        
        del writer #Forzar escritura a disco
        
        return QgsVectorLayer( fileName, self.name, "ogr")
Beispiel #21
0
    def create_shp(self):
        fields = QgsFields()
        fields.append(QgsField("setting_id", QVariant.String))
        fields.append(QgsField("raster", QVariant.String))
        fields.append(QgsField("x centre", QVariant.String))
        fields.append(QgsField("y centre", QVariant.String))

        self.shape_path = self.results.log_path.split(".log")[0] + ".shp"
        writer = QgsVectorFileWriter(
            self.shape_path,
            "CP1250",
            fields,
            QgsWkbTypes.Point,
            QgsCoordinateReferenceSystem(),
            "ESRI Shapefile",
        )
        try:
            if writer.hasError() != QgsVectorFileWriter.NoError:
                msg = "Error while creating shapefile: " + str(writer.errorMessage())
                logger.error(msg)
                raise Exception(msg)
            else:
                for pixel_check_dict in self.input_data_shp:
                    raster = pixel_check_dict.get("raster")
                    setting_id = pixel_check_dict.get("setting_id")
                    coords = pixel_check_dict.get("coords")
                    for row in coords:
                        for point in row:
                            point_y = point[0]
                            point_x = point[1]
                            feat = QgsFeature()
                            feat.setGeometry(
                                QgsGeometry.fromPointXY(QgsPointXY(point_x, point_y))
                            )
                            feat.setAttributes([setting_id, raster, point_x, point_y])
                            writer.addFeature(feat)
        except Exception:
            # TODO: there's a "raise" inside the try, there's a raise
            # below. What's the intention?
            logger.exception("Error creating shapefile")
            raise AssertionError("could not write XY point to shp file")
        # delete the writer to flush features to disk
        del writer
Beispiel #22
0
    def _toVectorLayer_geojson(self):
        crs = QgsCoordinateReferenceSystem()
        crs.createFromUserInput(self.provider.srsName)

        fileName = self.xmlFile.replace(".xml", ".geojson")
        fields = QgsFields()
        map(fields.append, self.provider.fields)
        writer = QgsVectorFileWriter(fileName, "utf-8", fields, QGis.WKBPoint,
                                     crs, "GeoJSON")

        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())

        for feature in self.provider.getFeatures():
            self.features.append(feature)
            writer.addFeature(feature)

        del writer  #Forzar escritura a disco

        return QgsVectorLayer(fileName, self.name, "ogr")
Beispiel #23
0
    def create_pipes_shp(shp_file_path, crs=None):

        fields = QgsFields()
        fields.append(QgsField(QgsField(Pipe.field_name_eid, QVariant.String)))
        # fields.append(QgsField(QgsField(Pipe.field_name_demand, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Pipe.field_name_diameter, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Pipe.field_name_length, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Pipe.field_name_roughness, QVariant.Double)))
        fields.append(
            QgsField(QgsField(Pipe.field_name_status, QVariant.String)))
        fields.append(
            QgsField(QgsField(Pipe.field_name_minor_loss, QVariant.Double)))

        writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields,
                                     QgsWkbTypes.LineString, crs,
                                     "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            raise Exception(writer.errorMessage())
Beispiel #24
0
def savePointGeometry(path, geodata, label, spatialRef, geoFormat):
    """
    :param label: Name of poles
    :param path: Location of shape file
    :param geodata: x, y and z coordinate of poles
    :param spatialRef: current spatial reference of qgis project
    :param geoFormat: Geodata export format
    """

    # Define fields for feature attributes. A QgsFields object is needed
    stueNrName = tr('bezeichnung')
    fields = QgsFields()
    fields.append(QgsField(stueNrName, QVariant.String, 'text', 254))
    fields.append(QgsField('x', QVariant.Double))
    fields.append(QgsField('y', QVariant.Double))
    fields.append(QgsField('z', QVariant.Double))
    fields.append(QgsField('h', QVariant.Double))
    writer = QgsVectorFileWriter(path, 'UTF-8', fields, QgsWkbTypes.PointZ,
                                 spatialRef, geoFormat)

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception('Vector Writer')

    features = []
    for idx, coords in enumerate(geodata):
        feature = QgsFeature()
        feature.setFields(fields)
        feature.setGeometry(QgsPoint(coords[0], coords[1], coords[2]))
        feature.setId(idx)
        feature.setAttribute(stueNrName, label[idx])
        feature.setAttribute('x', float(coords[0]))
        feature.setAttribute('y', float(coords[1]))
        feature.setAttribute('z', float(coords[2]))
        feature.setAttribute('h', float(coords[3]))
        features.append(feature)

    writer.addFeatures(features)
    # Delete the writer to flush features to disk
    del writer
Beispiel #25
0
def save2LineShape(shapePath, geodata, spatialRef):
    
    # define fields for feature attributes. A QgsFields object is needed
    fields = QgsFields()
    writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.LineStringZ,
                                 spatialRef, "ESRI Shapefile")

    if writer.hasError() != QgsVectorFileWriter.NoError:
        # TODO
        raise Exception("Vector Writer")

    lineVertices = []
    for idx, coords in enumerate(geodata):
        lineVertices.append(QgsPoint(coords[0], coords[1], coords[2]))
        
    feature = QgsFeature()
    feature.setGeometry(QgsGeometry.fromPolyline(lineVertices))
    feature.setId(1)
    writer.addFeature(feature)
    del feature
    # delete the writer to flush features to disk
    del writer
Beispiel #26
0
    def _newShapefile(self):
        fields = QgsFields()
        fields.append(QgsField('filepath', QVariant.String, '', 254))
        fields.append(QgsField('filename', QVariant.String, '', 254))
        fields.append(QgsField('longitude', QVariant.Double, '', 20, 7))
        fields.append(QgsField('latitude', QVariant.Double, '', 20, 7))
        fields.append(QgsField('altitude', QVariant.Double, '', 20, 7))
        fields.append(QgsField('north', QVariant.String, '', 1))
        fields.append(QgsField('azimuth', QVariant.Double, '', 20, 7))
        fields.append(QgsField('gps_date', QVariant.String, '', 254))
        fields.append(QgsField('img_date', QVariant.String, '', 254))

        crs = QgsCoordinateReferenceSystem(4326)
        writer = QgsVectorFileWriter(
            self.shapePath, self.encoding, fields, QGis.WKBPoint, crs)
        if writer.hasError() != QgsVectorFileWriter.NoError:
            return None
        del writer

        layer = QgsVectorLayer(
            self.shapePath, QFileInfo(self.shapePath).baseName(), 'ogr')
        return layer
 def to_shp(self, path, name, crs, encoding, geom_type, features, graph='primal'):
     if graph == 'primal':
         flds = self.edge_qflds
     elif graph == 'dual':
         flds = [QgsField('source', QVariant.String), QgsField('target', QVariant.String),
                        QgsField('cost', QVariant.Int)]
     if path is None:
         network = QgsVectorLayer('MultiLineString?crs=' + crs.toWkt(), name, "memory")
     else:
         file_writer = QgsVectorFileWriter(path, encoding, flds, geom_type,
                                           crs, "ESRI Shapefile")
         if file_writer.hasError() != QgsVectorFileWriter.NoError:
             print "Error when creating shapefile: ", file_writer.errorMessage()
         del file_writer
         network = QgsVectorLayer(path, name, "ogr")
     # QgsMapLayerRegistry.instance().addMapLayer(network)
     pr = network.dataProvider()
     network.startEditing()
     if path is None:
         pr.addAttributes(flds)
     pr.addFeatures(features)
     network.commitChanges()
     return network
Beispiel #28
0
def _clipVectorLayer(theLayer, theExtent,
                     extraKeywords=None):
    """Clip a Hazard or Exposure layer to the
    extents of the current view frame. The layer must be a
    vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    Args:

        * theLayer - a valid QGIS vector layer in EPSG:4326
        * theExtent -  an array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.

    Returns:
        Path to the output clipped layer (placed in the
        system temp dir).

    Raises:
       None

    """
    if not theLayer or not theExtent:
        msg = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterException(msg)

    if theLayer.type() != QgsMapLayer.VectorLayer:
        msg = tr('Expected a vector layer but received a %s.' %
                str(theLayer.type()))
        raise InvalidParameterException(msg)

    myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_',
                                            getTempDir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
    myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs())
    myRect = QgsRectangle(theExtent[0], theExtent[1],
                          theExtent[2], theExtent[3])
    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = theLayer.dataProvider()
    if myProvider is None:
        msg = tr('Could not obtain data provider from '
               'layer "%s"' % theLayer.source())
        raise Exception(msg)

    # get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #           different clipping behaviour e.g. reject polygons that
    #           intersect the edge of the bbox. Tim
    myAttributes = myProvider.attributeIndexes()
    myFetchGeometryFlag = True
    myUseIntersectFlag = True
    myProvider.select(myAttributes,
                      myProjectedExtent,
                      myFetchGeometryFlag,
                      myUseIntersectFlag)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(myFilename,
                                   'UTF-8',
                                   myFieldList,
                                   theLayer.wkbType(),
                                   myGeoCrs,
                                   'ESRI Shapefile')
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        msg = tr('Error when creating shapefile: <br>Filename:'
               '%s<br>Error: %s' %
            (myFilename, myWriter.hasError()))
        raise Exception(msg)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myFeature = QgsFeature()
    myCount = 0
    while myProvider.nextFeature(myFeature):
        myGeometry = myFeature.geometry()
        myGeometry.transform(myXForm)
        myFeature.setGeometry(myGeometry)
        myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr('No features fall within the clip extents. '
                       'Try panning / zooming to an area containing data '
                       'and then try to run your analysis again.')
        raise NoFeaturesInExtentException(myMessage)

    copyKeywords(theLayer.source(), myFilename, extraKeywords=extraKeywords)

    return myFilename  # Filename of created file
Beispiel #29
0
    def _preparePolygonLayer(self, theQgisLayer):
        """Create a new layer with no intersecting features to self.layer.

        A helper function to align the polygons to the postprocLayer
        polygons. If one input polygon is in two or more postprocLayer polygons
        then it is divided so that each part is within only one of the
        postprocLayer polygons. this allows to aggregate in postrocessing using
        centroid in polygon.

        The function assumes EPSG:4326 but no checks are enforced

        Args:
            theQgisLayer of the file to be processed
        Returns:
            QgisLayer of the processed file

        Raises:
            Any exceptions raised by the InaSAFE library will be propagated.
        """
#        import time
#        startTime = time.clock()

        myMessage = m.Message(
            m.Heading(self.tr('Preclipping input data...')),
            m.Paragraph(self.tr(
                'Modifying %1 to avoid intersections with the aggregation '
                'layer'
            ).arg(theQgisLayer.name())))
        self._sendMessage(myMessage)

        theLayerFilename = str(theQgisLayer.source())
        myPostprocPolygons = self.safeLayer.get_geometry()
        myPolygonsLayer = safe_read_layer(theLayerFilename)
        myRemainingPolygons = numpy.array(myPolygonsLayer.get_geometry())
#        myRemainingAttributes = numpy.array(myPolygonsLayer.get_data())
        myRemainingIndexes = numpy.array(range(len(myRemainingPolygons)))

        #used for unit tests only
        self.preprocessedFeatureCount = 0

        # FIXME (MB) the intersecting array is used only for debugging and
        # could be safely removed
        myIntersectingPolygons = []
        myInsidePolygons = []

        # FIXME (MB) maybe do raw geos without qgis
        #select all postproc polygons with no attributes
        aggregationProvider = self.layer.dataProvider()
        aggregationProvider.select([])

        # copy polygons to a memory layer
        myQgisMemoryLayer = create_memory_layer(theQgisLayer)

        polygonsProvider = myQgisMemoryLayer.dataProvider()
        allPolygonAttrs = polygonsProvider.attributeIndexes()
        polygonsProvider.select(allPolygonAttrs)
        myQgisPostprocPoly = QgsFeature()
        myQgisFeat = QgsFeature()
        myInsideFeat = QgsFeature()
        fields = polygonsProvider.fields()
        myTempdir = temp_dir(sub_dir='preprocess')
        myOutFilename = unique_filename(suffix='.shp',
                                        dir=myTempdir)

        self.keywordIO.copy_keywords(theQgisLayer, myOutFilename)
        mySHPWriter = QgsVectorFileWriter(myOutFilename,
                                          'UTF-8',
                                          fields,
                                          polygonsProvider.geometryType(),
                                          polygonsProvider.crs())
        if mySHPWriter.hasError():
            raise InvalidParameterError(mySHPWriter.errorMessage())
        # end FIXME

        for (myPostprocPolygonIndex,
             myPostprocPolygon) in enumerate(myPostprocPolygons):
            LOGGER.debug('PostprocPolygon %s' % myPostprocPolygonIndex)
            myPolygonsCount = len(myRemainingPolygons)
            aggregationProvider.featureAtId(
                myPostprocPolygonIndex, myQgisPostprocPoly, True, [])
            myQgisPostprocGeom = QgsGeometry(myQgisPostprocPoly.geometry())

            # myPostprocPolygon bounding box values
            A = numpy.array(myPostprocPolygon)
            minx = miny = sys.maxint
            maxx = maxy = -minx
            myPostprocPolygonMinx = min(minx, min(A[:, 0]))
            myPostprocPolygonMaxx = max(maxx, max(A[:, 0]))
            myPostprocPolygonMiny = min(miny, min(A[:, 1]))
            myPostprocPolygonMaxy = max(maxy, max(A[:, 1]))

            # create an array full of False to store if a BB vertex is inside
            # or outside the myPostprocPolygon
            myAreVerticesInside = numpy.zeros(myPolygonsCount * 4,
                                              dtype=numpy.bool)

            # Create Nx2 vector of vertices of bounding boxes
            myBBVertices = []
            # Compute bounding box for each geometry type
            for myPoly in myRemainingPolygons:
                minx = miny = sys.maxint
                maxx = maxy = -minx
                # Do outer ring only as the BB is outside anyway
                A = numpy.array(myPoly)
                minx = min(minx, numpy.min(A[:, 0]))
                maxx = max(maxx, numpy.max(A[:, 0]))
                miny = min(miny, numpy.min(A[:, 1]))
                maxy = max(maxy, numpy.max(A[:, 1]))
                myBBVertices.extend([(minx, miny),
                                    (minx, maxy),
                                    (maxx, maxy),
                                    (maxx, miny)])

            # see if BB vertices are in myPostprocPolygon
            myBBVertices = numpy.array(myBBVertices)
            inside, _ = points_in_and_outside_polygon(myBBVertices,
                                                      myPostprocPolygon)
            # make True if the vertice was in myPostprocPolygon
            myAreVerticesInside[inside] = True

            # myNextIterPolygons has the 0:count indexes
            # myOutsidePolygons has the mapped to original indexes
            # and is overwritten at every iteration because we care only of
            # the outside polygons remaining after the last iteration
            myNextIterPolygons = []
            myOutsidePolygons = []

            for i in range(myPolygonsCount):
                k = i * 4
                myMappedIndex = myRemainingIndexes[i]
                # memory layers counting starts at 1 instead of 0 as in our
                # indexes
                myFeatId = myMappedIndex + 1
                doIntersection = False
                # summ the isInside bool for each of the boundingbox vertices
                # of each poygon. for example True + True + False + True is 3
                myPolygonLocation = numpy.sum(myAreVerticesInside[k:k + 4])

                if myPolygonLocation == 4:
                    # all vertices are inside -> polygon is inside
                    #ignore this polygon from further analysis
                    myInsidePolygons.append(myMappedIndex)
                    polygonsProvider.featureAtId(myFeatId,
                                                 myQgisFeat,
                                                 True,
                                                 allPolygonAttrs)
                    mySHPWriter.addFeature(myQgisFeat)
                    self.preprocessedFeatureCount += 1
#                    LOGGER.debug('Polygon %s is fully inside' %myMappedIndex)
#                    tmpWriter.addFeature(myQgisFeat)

                elif myPolygonLocation == 0:
                    # all vertices are outside
                    # check if the polygon BB is completely outside of the
                    # myPostprocPolygon BB.
                    myPolyMinx = numpy.min(myBBVertices[k:k + 4, 0])
                    myPolyMaxx = numpy.max(myBBVertices[k:k + 4, 0])
                    myPolyMiny = numpy.min(myBBVertices[k:k + 4, 1])
                    myPolyMaxy = numpy.max(myBBVertices[k:k + 4, 1])

                    # check if myPoly is all E,W,N,S of myPostprocPolygon
                    if ((myPolyMinx > myPostprocPolygonMaxx) or
                            (myPolyMaxx < myPostprocPolygonMinx) or
                            (myPolyMiny > myPostprocPolygonMaxy) or
                            (myPolyMaxy < myPostprocPolygonMiny)):
                        #polygon is surely outside
                        myOutsidePolygons.append(myMappedIndex)
                        # we need this polygon in the next iteration
                        myNextIterPolygons.append(i)
                    else:
                        # polygon might be outside or intersecting. consider
                        # it intersecting so it goes into further analysis
                        doIntersection = True
                else:
                    # some vertices are outside some inside -> polygon is
                    # intersecting
                    doIntersection = True

                #intersect using qgis
                if doIntersection:
#                    LOGGER.debug('Intersecting polygon %s' % myMappedIndex)
                    myIntersectingPolygons.append(myMappedIndex)

                    ok = polygonsProvider.featureAtId(myFeatId,
                                                      myQgisFeat,
                                                      True,
                                                      allPolygonAttrs)
                    if not ok:
                        LOGGER.debug('Couldn\'t fetch feature: %s' % myFeatId)
                        LOGGER.debug([str(error) for error in
                                      polygonsProvider.errors()])

                    myQgisPolyGeom = QgsGeometry(myQgisFeat.geometry())
                    myAtMap = myQgisFeat.attributeMap()
#                    for (k, attr) in myAtMap.iteritems():
#                        LOGGER.debug( "%d: %s" % (k, attr.toString()))

                    # make intersection of the myQgisFeat and the postprocPoly
                    # write the inside part to a shp file and the outside part
                    # back to the original QGIS layer
                    try:
                        myIntersec = myQgisPostprocGeom.intersection(
                            myQgisPolyGeom)
#                        if myIntersec is not None:
                        myIntersecGeom = QgsGeometry(myIntersec)

                        #from ftools
                        myUnknownGeomType = 0
                        if myIntersecGeom.wkbType() == myUnknownGeomType:
                            int_com = myQgisPostprocGeom.combine(
                                myQgisPolyGeom)
                            int_sym = myQgisPostprocGeom.symDifference(
                                myQgisPolyGeom)
                            myIntersecGeom = QgsGeometry(
                                int_com.difference(int_sym))
#                        LOGGER.debug('wkbType type of intersection: %s' %
# myIntersecGeom.wkbType())
                        polygonTypesList = [QGis.WKBPolygon,
                                            QGis.WKBMultiPolygon]
                        if myIntersecGeom.wkbType() in polygonTypesList:
                            myInsideFeat.setGeometry(myIntersecGeom)
                            myInsideFeat.setAttributeMap(myAtMap)
                            mySHPWriter.addFeature(myInsideFeat)
                            self.preprocessedFeatureCount += 1
                        else:
                            pass
#                            LOGGER.debug('Intersection not a polygon so '
#                                         'the two polygons either touch '
#                                         'only or do not intersect. Not '
#                                         'adding this to the inside list')
                        #Part of the polygon that is outside the postprocpoly
                        myOutside = myQgisPolyGeom.difference(myIntersecGeom)
#                        if myOutside is not None:
                        myOutsideGeom = QgsGeometry(myOutside)

                        if myOutsideGeom.wkbType() in polygonTypesList:
                            # modifiy the original geometry to the part
                            # outside of the postproc polygon
                            polygonsProvider.changeGeometryValues(
                                {myFeatId: myOutsideGeom})
                            # we need this polygon in the next iteration
                            myOutsidePolygons.append(myMappedIndex)
                            myNextIterPolygons.append(i)

                    except TypeError:
                        LOGGER.debug('ERROR with FID %s', myMappedIndex)

#            LOGGER.debug('Inside %s' % myInsidePolygons)
#            LOGGER.debug('Outside %s' % myOutsidePolygons)
#            LOGGER.debug('Intersec %s' % myIntersectingPolygons)
            if len(myNextIterPolygons) > 0:
                #some polygons are still completely outside of the postprocPoly
                #so go on and reiterate using only these
                nextIterPolygonsIndex = numpy.array(myNextIterPolygons)

                myRemainingPolygons = myRemainingPolygons[
                    nextIterPolygonsIndex]
#                myRemainingAttributes = myRemainingAttributes[
#                                        nextIterPolygonsIndex]
                myRemainingIndexes = myRemainingIndexes[nextIterPolygonsIndex]
                LOGGER.debug('Remaining: %s' % len(myRemainingPolygons))
            else:
                print 'no more polygons to be checked'
                break
#            del tmpWriter

        # here the full polygon set is represented by:
        # myInsidePolygons + myIntersectingPolygons + myNextIterPolygons
        # the a polygon intersecting multiple postproc polygons appears
        # multiple times in the array
        # noinspection PyUnboundLocalVariable
        LOGGER.debug('Results:\nInside: %s\nIntersect: %s\nOutside: %s' % (
            myInsidePolygons, myIntersectingPolygons, myOutsidePolygons))

        #add in- and outside polygons

        for i in myOutsidePolygons:
            myFeatId = i + 1
            polygonsProvider.featureAtId(myFeatId, myQgisFeat, True,
                                         allPolygonAttrs)
            mySHPWriter.addFeature(myQgisFeat)
            self.preprocessedFeatureCount += 1

        del mySHPWriter
#        LOGGER.debug('Created: %s' % self.preprocessedFeatureCount)

        myName = '%s %s' % (theQgisLayer.name(), self.tr('preprocessed'))
        myOutLayer = QgsVectorLayer(myOutFilename, myName, 'ogr')
        if not myOutLayer.isValid():
            #TODO (MB) use a better exception
            raise Exception('Invalid qgis Layer')

        if self.showIntermediateLayers:
            self.keywordIO.update_keywords(myOutLayer, {'title': myName})
            QgsMapLayerRegistry.instance().addMapLayer(myOutLayer)

        return myOutLayer
# Export a vector layer directly from features
# define fields for feature attributes. A QgsFields object is needed
fields = QgsFields()
fields.append(QgsField("first", QVariant.Int))
fields.append(QgsField("second", QVariant.String))

# Create an instance of vector file writer, which will create the vector file.
# Arguments:
# 1. path to new file (will fail if exists already)
# 2. encoding of the attributes
# 3. field map
# 4. geometry type - from WKBTYPE enum
# 5. layer's spatial reference (instance of
#    QgsCoordinateReferenceSystem) - optional
# 6. driver name for the output file
writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields, QGis.WKBPoint,
                             None, "ESRI Shapefile")

if writer.hasError() != QgsVectorFileWriter.NoError:
    print("Error when creating shapefile: ", writer.errorMessage())

# Add a feature
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
fet.setAttributes([1, "text"])
writer.addFeature(fet)

# Delete the writer to flush features to disk
del writer
Beispiel #31
0
def _clipVectorLayer(theLayer, theExtent, theExtraKeywords=None, explodeMultipart=True):
    """Clip a Hazard or Exposure layer to the
    extents of the current view frame. The layer must be a
    vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    Args:

        * theLayer - a valid QGIS vector layer in EPSG:4326
        * theExtent -  an array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.
        * theExtraKeywords - any additional keywords over and above the
          original keywords that should be associated with the cliplayer.
        * explodeMultipart - a bool describing if to convert multipart
        features into singleparts

    Returns:
        Path to the output clipped layer (placed in the
        system temp dir).

    Raises:
       None

    """
    if not theLayer or not theExtent:
        myMessage = tr("Layer or Extent passed to clip is None.")
        raise InvalidParameterException(myMessage)

    if theLayer.type() != QgsMapLayer.VectorLayer:
        myMessage = tr("Expected a vector layer but received a %s." % str(theLayer.type()))
        raise InvalidParameterException(myMessage)

    # myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    myHandle, myFilename = tempfile.mkstemp(".shp", "clip_", temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
    myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs())
    myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2], theExtent[3])
    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = theLayer.dataProvider()
    if myProvider is None:
        myMessage = tr("Could not obtain data provider from " 'layer "%s"' % theLayer.source())
        raise Exception(myMessage)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    myAttributes = myProvider.attributeIndexes()
    myFetchGeometryFlag = True
    myUseIntersectFlag = True
    myProvider.select(myAttributes, myProjectedExtent, myFetchGeometryFlag, myUseIntersectFlag)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(
        myFilename,
        "UTF-8",
        myFieldList,
        theLayer.wkbType(),
        myGeoCrs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        "ESRI Shapefile",
    )
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        myMessage = tr(
            "Error when creating shapefile: <br>Filename:" "%s<br>Error: %s" % (myFilename, myWriter.hasError())
        )
        raise Exception(myMessage)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myFeature = QgsFeature()
    myCount = 0
    while myProvider.nextFeature(myFeature):
        myGeometry = myFeature.geometry()
        # Loop through the parts adding them to the output file
        # we write out single part features unless explodeMultipart is False
        if explodeMultipart:
            myGeometryList = explodeMultiPartGeometry(myGeometry)
        else:
            myGeometryList = [myGeometry]

        for myPart in myGeometryList:
            myPart.transform(myXForm)
            myFeature.setGeometry(myPart)
            myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr(
            "No features fall within the clip extents. "
            "Try panning / zooming to an area containing data "
            "and then try to run your analysis again."
        )
        raise NoFeaturesInExtentException(myMessage)

    myKeywordIO = KeywordIO()
    myKeywordIO.copyKeywords(theLayer, myFilename, theExtraKeywords=theExtraKeywords)

    return myFilename  # Filename of created file
Beispiel #32
0
def _clipVectorLayer(theLayer,
                     theExtent,
                     theExtraKeywords=None,
                     explodeMultipart=True):
    """Clip a Hazard or Exposure layer to the
    extents of the current view frame. The layer must be a
    vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    Args:

        * theLayer - a valid QGIS vector layer in EPSG:4326
        * theExtent -  an array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.
        * theExtraKeywords - any additional keywords over and above the
          original keywords that should be associated with the cliplayer.
        * explodeMultipart - a bool describing if to convert multipart
        features into singleparts

    Returns:
        Path to the output clipped layer (placed in the
        system temp dir).

    Raises:
       None

    """
    if not theLayer or not theExtent:
        myMessage = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterException(myMessage)

    if theLayer.type() != QgsMapLayer.VectorLayer:
        myMessage = tr('Expected a vector layer but received a %s.' %
                       str(theLayer.type()))
        raise InvalidParameterException(myMessage)

    #myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_', temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
    myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs())
    myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2],
                          theExtent[3])
    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = theLayer.dataProvider()
    if myProvider is None:
        myMessage = tr('Could not obtain data provider from '
                       'layer "%s"' % theLayer.source())
        raise Exception(myMessage)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    myAttributes = myProvider.attributeIndexes()
    myFetchGeometryFlag = True
    myUseIntersectFlag = True
    myProvider.select(myAttributes, myProjectedExtent, myFetchGeometryFlag,
                      myUseIntersectFlag)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(
        myFilename,
        'UTF-8',
        myFieldList,
        theLayer.wkbType(),
        myGeoCrs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        myMessage = tr('Error when creating shapefile: <br>Filename:'
                       '%s<br>Error: %s' % (myFilename, myWriter.hasError()))
        raise Exception(myMessage)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myFeature = QgsFeature()
    myCount = 0
    while myProvider.nextFeature(myFeature):
        myGeometry = myFeature.geometry()
        # Loop through the parts adding them to the output file
        # we write out single part features unless explodeMultipart is False
        if explodeMultipart:
            myGeometryList = explodeMultiPartGeometry(myGeometry)
        else:
            myGeometryList = [myGeometry]

        for myPart in myGeometryList:
            myPart.transform(myXForm)
            myFeature.setGeometry(myPart)
            myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr('No features fall within the clip extents. '
                       'Try panning / zooming to an area containing data '
                       'and then try to run your analysis again.')
        raise NoFeaturesInExtentException(myMessage)

    myKeywordIO = KeywordIO()
    myKeywordIO.copyKeywords(theLayer,
                             myFilename,
                             theExtraKeywords=theExtraKeywords)

    return myFilename  # Filename of created file
Beispiel #33
0
    def processSampleRasterAlgorithm(self, pointSpacing, INPUT_EXTENT,
                                     SAMPLE_FILE, OUTPUT_FILE, feedback):
        if (os.path.isfile(OUTPUT_FILE)):
            return 0

        fields = QgsFields()
        fields.append(QgsField("slope", QVariant.Double))

        sampleLayer = QgsRasterLayer(SAMPLE_FILE, 'Reclassified Slope', 'gdal')

        #pointLayerPath = quote(INPUT_POINTS)
        #pointLayer = QgsVectorLayer(pointLayerPath, 'points', 'ogr')
        QgsMessageLog.logMessage(
            'Now generate points: extent={} crs={}'.format(
                INPUT_EXTENT.toString(),
                sampleLayer.crs().description()))
        pointLayer = processing.run('qgis:regularpoints', {
            'EXTENT': INPUT_EXTENT,
            'SPACING': pointSpacing,
            'INSET': 0,
            'IS_SPACING': True,
            'RANDOMIZE': False,
            'CRS': sampleLayer.crs().description(),
            'OUTPUT': 'memory:'
        },
                                    feedback=feedback)['OUTPUT']

        #QgsMessageLog.logMessage("Points done!")
        #QgsMessageLog.logMessage("Now build sample points destination")
        sampledPointsLayerPath = OUTPUT_FILE
        sampledPointsLayer = QgsVectorFileWriter(sampledPointsLayerPath,
                                                 "utf-8", fields,
                                                 QgsWkbTypes.Point,
                                                 sampleLayer.crs(),
                                                 "ESRI Shapefile")

        result = sampledPointsLayer.hasError()
        QgsMessageLog.logMessage(
            "INITIAL ERROR CHECK, CODE: {}, MSG: {}".format(
                result, sampledPointsLayer.errorMessage()))
        if result > 0:
            return result

        #QgsMessageLog.logMessage("Does writer have error? {}, {}".format(sampledPointsLayer.hasError(), sampledPointsLayer.errorMessage()))
        #QgsMessageLog.logMessage("Will sample {} points".format(pointLayer.featureCount()))

        count = pointLayer.featureCount()
        total = 100.0 / count if count else 0
        features = pointLayer.getFeatures(QgsFeatureRequest())
        current = 0
        featureGroups = chunks(features, count, 100)
        QgsMessageLog.logMessage("FEATURE COUNT: {}".format(count))
        for group in featureGroups:
            for feature in group:
                # Stop the algorithm if cancel button has been clicked
                #QgsMessageLog.logMessage("Current: {}".format(current))
                #QgsMessageLog.logMessage("Feature: {}".format(feature))
                if feedback.isCanceled():
                    break
                current = current + 1
                ident = sampleLayer.dataProvider().identify(
                    feature.geometry().asPoint(),
                    QgsRaster.IdentifyFormatValue)
                if (ident.results()[1]) is not None and int(
                        ident.results()[1]) == 1:
                    out_point = QgsFeature(fields)
                    out_point.setGeometry(feature.geometry())
                    out_point.setAttribute('slope', ident.results()[1])
                    sampledPointsLayer.addFeature(out_point,
                                                  QgsFeatureSink.FastInsert)

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

        result = sampledPointsLayer.hasError()
        del sampledPointsLayer
        return result
Beispiel #34
0
def points_along_line(layerout,
                      startpoint,
                      endpoint,
                      distance,
                      label,
                      layer,
                      selected_only=True,
                      force=False,
                      fo_fila=False,
                      divide=0,
                      decimal=2):
    """Adding Points along the line
    """

    crs = layer.crs().authid()

    # TODO check for virtual or shapelayer and set virt_layer according to it
    shape = False
    if shape:
        # define fields for feature attributes. A list of QgsField objects is needed
        fields = [
            QgsField("first", QVariant.Int),
            QgsField("second", QVariant.String)
        ]
        # create an instance of vector file writer, which will create the vector file.
        # Arguments:
        # 1. path to new file (will fail if exists already)
        # 2. encoding of the attributes
        # 3. field map
        # 4. geometry type - from WKBTYPE enum
        # 5. layer's spatial reference (instance of
        #    QgsCoordinateReferenceSystem) - optional
        # 6. driver name for the output file
        writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields,
                                     Qgis.WKBPoint, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            # fix_print_with_import
            print("Error when creating shapefile: ", writer.hasError())
        # add a feature
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        fet.setAttributes([1, "text"])
        writer.addFeature(fet)
        # delete the writer to flush features to disk (optional)
        del writer

        layer_type = "Shapefile"  # TODO Add Shapefile functionality here
    else:
        layer_type = "memory"

    virt_layer = QgsVectorLayer("Point?crs=%s" % crs, layerout, layer_type)
    provider = virt_layer.dataProvider()
    virt_layer.startEditing()  # actually writes attributes

    units = layer.crs().mapUnits()

    unitname = QgsUnitTypes.toString(units)
    provider.addAttributes([
        QgsField("fid", QVariant.Int),
        QgsField("cng" + unitname, QVariant.Double)
    ])

    def get_features():
        """Getting the features
        """
        if selected_only:
            return layer.selectedFeatures()
        else:
            return layer.getFeatures()

    # Loop through all (selected) features
    for feature in get_features():
        geom = feature.geometry()
        # Add feature ID of selected feature
        fid = feature.id()
        if not geom:
            QgsMessageLog.logMessage("No geometry", "QChainage")
            continue

        features = create_points_at(startpoint, endpoint, distance, geom, fid,
                                    force, fo_fila, divide)
        provider.addFeatures(features)
        virt_layer.updateExtents()

    proj = QgsProject.instance()
    proj.addMapLayers([virt_layer])
    virt_layer.commitChanges()
    virt_layer.reload()

    # generic labeling properties
    if label:
        virt_layer.setCustomProperty("labeling", "pal")
        virt_layer.setCustomProperty("labeling/enabled", "true")
        virt_layer.setCustomProperty("labeling/fieldName", "cng")
        virt_layer.setCustomProperty("labeling/fontSize", "10")
        virt_layer.setCustomProperty("labeling/multiLineLabels", "true")
        virt_layer.setCustomProperty("labeling/formatNumbers", "true")
        virt_layer.setCustomProperty("labeling/decimals", decimal)
        virt_layer.setCustomProperty("labeling/Size", "5")
    # symbol = QgsMarkerSymbol.createSimple({"name": "capital"})
    # virt_layer.setRenderer(QgsSingleSymbolRenderer(symbol))
    virt_layer.triggerRepaint()
    return
Beispiel #35
0
def _clipVectorLayer(theLayer,
                     theExtent,
                     theExtraKeywords=None,
                     theExplodeFlag=True,
                     theHardClipFlag=False):
    """Clip a Hazard or Exposure layer to the
    extents of the current view frame. The layer must be a
    vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    Args:

        * theLayer - a valid QGIS vector layer in EPSG:4326
        * theExtent either: an array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.
                    or: A QgsGeometry of type polygon. **Polygon clipping is
           currently only supported for vector datasets.**
        * theExtraKeywords - any additional keywords over and above the
          original keywords that should be associated with the cliplayer.
        * theExplodeFlag - a bool specifying whether multipart features
            should be 'exploded' into singleparts.
        * theHardClipFlag - a bool specifying whether line and polygon features
            that extend beyond the extents should be clipped such that they
            are reduced in size to the part of the geometry that intersects
            the extent only. Default is False.

    Returns:
        Path to the output clipped layer (placed in the system temp dir).

    Raises:
       None

    """
    if not theLayer or not theExtent:
        myMessage = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(myMessage)

    if theLayer.type() != QgsMapLayer.VectorLayer:
        myMessage = tr('Expected a vector layer but received a %s.' %
                       str(theLayer.type()))
        raise InvalidParameterError(myMessage)

    #myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_', temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
    myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs())
    myAllowedClipTypes = [QGis.WKBPolygon, QGis.WKBPolygon25D]
    if type(theExtent) is list:
        myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2],
                              theExtent[3])
        # noinspection PyCallByClass
        myClipPolygon = QgsGeometry.fromRect(myRect)
    elif (type(theExtent) is QgsGeometry
          and theExtent.wkbType in myAllowedClipTypes):
        myRect = theExtent.boundingBox().toRectF()
        myClipPolygon = theExtent
    else:
        raise InvalidClipGeometryError(
            tr('Clip geometry must be an extent or a single part'
               'polygon based geometry.'))

    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = theLayer.dataProvider()
    if myProvider is None:
        myMessage = tr('Could not obtain data provider from '
                       'layer "%s"' % theLayer.source())
        raise Exception(myMessage)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    myAttributes = myProvider.attributeIndexes()
    myFetchGeometryFlag = True
    myUseIntersectFlag = True
    myProvider.select(myAttributes, myProjectedExtent, myFetchGeometryFlag,
                      myUseIntersectFlag)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(
        myFilename,
        'UTF-8',
        myFieldList,
        theLayer.wkbType(),
        myGeoCrs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        myMessage = tr('Error when creating shapefile: <br>Filename:'
                       '%s<br>Error: %s' % (myFilename, myWriter.hasError()))
        raise Exception(myMessage)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myFeature = QgsFeature()
    myCount = 0
    while myProvider.nextFeature(myFeature):
        myGeometry = myFeature.geometry()
        # Loop through the parts adding them to the output file
        # we write out single part features unless theExplodeFlag is False
        if theExplodeFlag:
            myGeometryList = explodeMultiPartGeometry(myGeometry)
        else:
            myGeometryList = [myGeometry]

        for myPart in myGeometryList:
            myPart.transform(myXForm)
            if theHardClipFlag:
                # Remove any dangling bits so only intersecting area is
                # kept.
                myPart = clipGeometry(myClipPolygon, myPart)
            if myPart is None:
                continue
            myFeature.setGeometry(myPart)
            myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr('No features fall within the clip extents. '
                       'Try panning / zooming to an area containing data '
                       'and then try to run your analysis again.'
                       'If hazard and exposure data doesn\'t overlap '
                       'at all, it is not possible to do an analysis.'
                       'Another possibility is that the layers do overlap '
                       'but because they may have different spatial '
                       'references, they appear to be disjoint. '
                       'If this is the case, try to turn on reproject '
                       'on-the-fly in QGIS.')
        raise NoFeaturesInExtentError(myMessage)

    myKeywordIO = KeywordIO()
    myKeywordIO.copyKeywords(theLayer,
                             myFilename,
                             theExtraKeywords=theExtraKeywords)

    return myFilename  # Filename of created file
Beispiel #36
0
def _clip_vector_layer(
        layer,
        extent,
        extra_keywords=None,
        explode_flag=True,
        hard_clip_flag=False,
        explode_attribute=None):
    """Clip a Hazard or Exposure layer to the extents provided.

    The layer must be a vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    :param layer: A valid QGIS vector or raster layer
    :type layer:

    :param extent: Either an array representing the exposure layer extents
        in the form [xmin, ymin, xmax, ymax]. It is assumed that the
        coordinates are in EPSG:4326 although currently no checks are made to
        enforce this.
        or:
        A QgsGeometry of type polygon.
        **Polygon clipping is currently only supported for vector datasets.**
    :type extent: list(float, float, float, float)

    :param extra_keywords: Optional keywords dictionary to be added to
        output layer.
    :type extra_keywords: dict

    :param explode_flag: A bool specifying whether multipart features
        should be 'exploded' into singleparts.
        **This parameter is ignored for raster layer clipping.**
    :type explode_flag: bool

    :param hard_clip_flag: A bool specifying whether line and polygon
        features that extend beyond the extents should be clipped such that
        they are reduced in size to the part of the geometry that intersects
        the extent only. Default is False.
        **This parameter is ignored for raster layer clipping.**
    :type hard_clip_flag: bool

    :param explode_attribute: A str specifying to which attribute #1,
        #2 and so on will be added in case of explode_flag being true. The
        attribute is modified only if there are at least 2 parts.
    :type explode_attribute: str

    :returns: Clipped layer (placed in the system temp dir). The output layer
        will be reprojected to EPSG:4326 if needed.
    :rtype: QgsVectorLayer

    """
    if not layer or not extent:
        myMessage = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(myMessage)

    if layer.type() != QgsMapLayer.VectorLayer:
        myMessage = tr('Expected a vector layer but received a %s.' %
                       str(layer.type()))
        raise InvalidParameterError(myMessage)

    #myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_',
                                            temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromSrid(4326)
    myXForm = QgsCoordinateTransform(myGeoCrs, layer.crs())
    myAllowedClipTypes = [QGis.WKBPolygon, QGis.WKBPolygon25D]
    if type(extent) is list:
        myRect = QgsRectangle(
            extent[0], extent[1],
            extent[2], extent[3])
        # noinspection PyCallByClass
        myClipPolygon = QgsGeometry.fromRect(myRect)
    elif (type(extent) is QgsGeometry and
          extent.wkbType in myAllowedClipTypes):
        myRect = extent.boundingBox().toRectF()
        myClipPolygon = extent
    else:
        raise InvalidClipGeometryError(
            tr(
                'Clip geometry must be an extent or a single part'
                'polygon based geometry.'))

    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = layer.dataProvider()
    if myProvider is None:
        myMessage = tr('Could not obtain data provider from '
                       'layer "%s"' % layer.source())
        raise Exception(myMessage)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    myRequest = QgsFeatureRequest()
    if not myProjectedExtent.isEmpty():
        myRequest.setFilterRect(myProjectedExtent)
        myRequest.setFlags(QgsFeatureRequest.ExactIntersect)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(
        myFilename,
        'UTF-8',
        myFieldList,
        layer.wkbType(),
        myGeoCrs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        myMessage = tr('Error when creating shapefile: <br>Filename:'
                       '%s<br>Error: %s' %
                       (myFilename, myWriter.hasError()))
        raise Exception(myMessage)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(layer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myCount = 0
    myHasMultipart = False

    for myFeature in myProvider.getFeatures(myRequest):
        myGeometry = myFeature.geometry()

        # Loop through the parts adding them to the output file
        # we write out single part features unless explode_flag is False
        if explode_flag:
            myGeometryList = explode_multipart_geometry(myGeometry)
        else:
            myGeometryList = [myGeometry]

        for myPartIndex, myPart in enumerate(myGeometryList):
            myPart.transform(myXForm)
            if hard_clip_flag:
                # Remove any dangling bits so only intersecting area is
                # kept.
                myPart = clip_geometry(myClipPolygon, myPart)
            if myPart is None:
                continue

            myFeature.setGeometry(myPart)
            # There are multiple parts and we want to show it in the
            # explode_attribute
            if myPartIndex > 0 and explode_attribute is not None:
                myHasMultipart = True

            myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr(
            'No features fall within the clip extents. Try panning / zooming '
            'to an area containing data and then try to run your analysis '
            'again. If hazard and exposure data doesn\'t overlap at all, it '
            'is not possible to do an analysis. Another possibility is that '
            'the layers do overlap but because they may have different '
            'spatial references, they appear to be disjointed. If this is the '
            'case, try to turn on reproject on-the-fly in QGIS.')
        raise NoFeaturesInExtentError(myMessage)

    myKeywordIO = KeywordIO()
    if extra_keywords is None:
        extra_keywords = {}
    extra_keywords['had multipart polygon'] = myHasMultipart
    myKeywordIO.copy_keywords(
        layer, myFilename, extra_keywords=extra_keywords)
    myBaseName = '%s clipped' % layer.name()
    myLayer = QgsVectorLayer(myFilename, myBaseName, 'ogr')

    return myLayer
Beispiel #37
0
def _clipVectorLayer(theLayer,
                     theExtent,
                     theExtraKeywords=None,
                     theExplodeFlag=True,
                     theHardClipFlag=False):
    """Clip a Hazard or Exposure layer to the
    extents of the current view frame. The layer must be a
    vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    Args:

        * theLayer - a valid QGIS vector layer in EPSG:4326
        * theExtent either: an array representing the exposure layer
           extents in the form [xmin, ymin, xmax, ymax]. It is assumed
           that the coordinates are in EPSG:4326 although currently
           no checks are made to enforce this.
                    or: A QgsGeometry of type polygon. **Polygon clipping is
           currently only supported for vector datasets.**
        * theExtraKeywords - any additional keywords over and above the
          original keywords that should be associated with the cliplayer.
        * theExplodeFlag - a bool specifying whether multipart features
            should be 'exploded' into singleparts.
        * theHardClipFlag - a bool specifying whether line and polygon features
            that extend beyond the extents should be clipped such that they
            are reduced in size to the part of the geometry that intersects
            the extent only. Default is False.

    Returns:
        Path to the output clipped layer (placed in the system temp dir).

    Raises:
       None

    """
    if not theLayer or not theExtent:
        myMessage = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(myMessage)

    if theLayer.type() != QgsMapLayer.VectorLayer:
        myMessage = tr('Expected a vector layer but received a %s.' %
                       str(theLayer.type()))
        raise InvalidParameterError(myMessage)

    #myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_',
                                            temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(myHandle)
    os.remove(myFilename)

    # Get the clip extents in the layer's native CRS
    myGeoCrs = QgsCoordinateReferenceSystem()
    myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
    myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs())
    myAllowedClipTypes = [QGis.WKBPolygon, QGis.WKBPolygon25D]
    if type(theExtent) is list:
        myRect = QgsRectangle(
            theExtent[0], theExtent[1],
            theExtent[2], theExtent[3])
        # noinspection PyCallByClass
        myClipPolygon = QgsGeometry.fromRect(myRect)
    elif (type(theExtent) is QgsGeometry and
          theExtent.wkbType in myAllowedClipTypes):
        myRect = theExtent.boundingBox().toRectF()
        myClipPolygon = theExtent
    else:
        raise InvalidClipGeometryError(
            tr(
                'Clip geometry must be an extent or a single part'
                'polygon based geometry.'))

    myProjectedExtent = myXForm.transformBoundingBox(myRect)

    # Get vector layer
    myProvider = theLayer.dataProvider()
    if myProvider is None:
        myMessage = tr('Could not obtain data provider from '
                       'layer "%s"' % theLayer.source())
        raise Exception(myMessage)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    myAttributes = myProvider.attributeIndexes()
    myFetchGeometryFlag = True
    myUseIntersectFlag = True
    myProvider.select(
        myAttributes,
        myProjectedExtent,
        myFetchGeometryFlag,
        myUseIntersectFlag)

    myFieldList = myProvider.fields()

    myWriter = QgsVectorFileWriter(
        myFilename,
        'UTF-8',
        myFieldList,
        theLayer.wkbType(),
        myGeoCrs,
        #'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if myWriter.hasError() != QgsVectorFileWriter.NoError:
        myMessage = tr('Error when creating shapefile: <br>Filename:'
                       '%s<br>Error: %s' %
                       (myFilename, myWriter.hasError()))
        raise Exception(myMessage)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs)
    # Retrieve every feature with its geometry and attributes
    myFeature = QgsFeature()
    myCount = 0
    while myProvider.nextFeature(myFeature):
        myGeometry = myFeature.geometry()
        # Loop through the parts adding them to the output file
        # we write out single part features unless theExplodeFlag is False
        if theExplodeFlag:
            myGeometryList = explodeMultiPartGeometry(myGeometry)
        else:
            myGeometryList = [myGeometry]

        for myPart in myGeometryList:
            myPart.transform(myXForm)
            if theHardClipFlag:
                # Remove any dangling bits so only intersecting area is
                # kept.
                myPart = clipGeometry(myClipPolygon, myPart)
            if myPart is None:
                continue
            myFeature.setGeometry(myPart)
            myWriter.addFeature(myFeature)
        myCount += 1
    del myWriter  # Flush to disk

    if myCount < 1:
        myMessage = tr('No features fall within the clip extents. '
                       'Try panning / zooming to an area containing data '
                       'and then try to run your analysis again.'
                       'If hazard and exposure data doesn\'t overlap '
                       'at all, it is not possible to do an analysis.'
                       'Another possibility is that the layers do overlap '
                       'but because they may have different spatial '
                       'references, they appear to be disjoint. '
                       'If this is the case, try to turn on reproject '
                       'on-the-fly in QGIS.')
        raise NoFeaturesInExtentError(myMessage)

    myKeywordIO = KeywordIO()
    myKeywordIO.copyKeywords(
        theLayer, myFilename, theExtraKeywords=theExtraKeywords)

    return myFilename  # Filename of created file
# Export a vector layer directly from features
# define fields for feature attributes. A QgsFields object is needed
fields = QgsFields()
fields.append(QgsField("first", QVariant.Int))
fields.append(QgsField("second", QVariant.String))

# Create an instance of vector file writer, which will create the vector file.
# Arguments:
# 1. path to new file (will fail if exists already)
# 2. encoding of the attributes
# 3. field map
# 4. geometry type - from WKBTYPE enum
# 5. layer's spatial reference (instance of
#    QgsCoordinateReferenceSystem) - optional
# 6. driver name for the output file
writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields,
                             QGis.WKBPoint, None, "ESRI Shapefile")

if writer.hasError() != QgsVectorFileWriter.NoError:
    print("Error when creating shapefile: ", writer.errorMessage())

# Add a feature
fet = QgsFeature()
fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
fet.setAttributes([1, "text"])
writer.addFeature(fet)

# Delete the writer to flush features to disk
del writer
Beispiel #39
0
    def run(self):
        # index = 0
        arrmat = np.empty((1, 8))

        # #Check OS and dep
        # if sys.platform == 'darwin':
        #     gdalwarp_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/gdalwarp'
        # else:
        #     gdalwarp_os_dep = 'gdalwarp'

        ret = 0
        imp_point = 0

        # Allt arbete en trad ska utforas maste goras i en try-sats
        try:
            # j = 0
            # Loop som utfor det arbete som annars hade "hangt" anvandargranssnittet i Qgis
            pre = self.dlg.textOutput_prefix.text()
            header = ' Wd pai   fai   zH  zHmax   zHstd zd z0'
            numformat = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f'
            header2 = ' id  pai   fai   zH  zHmax   zHstd  zd  z0'
            numformat2 = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f'

            # temporary fix for mac, ISSUE #15
            pf = sys.platform
            if pf == 'darwin' or pf == 'linux2':
                if not os.path.exists(self.folderPath[0] + '/' + pre):
                    os.makedirs(self.folderPath[0] + '/' + pre)

            for f in self.vlayer.getFeatures(
            ):  # looping through each grid polygon
                # Kollar sa att traden inte har avbrutits, ifall den har det sa slutar loopning.
                if self.killed is True:
                    break
                # pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True) #used for debugging

                attributes = f.attributes()
                geometry = f.geometry()
                feature = QgsFeature()
                feature.setAttributes(attributes)
                feature.setGeometry(geometry)

                if self.imid == 1:  # use center point
                    r = self.radius
                    y = f.geometry().centroid().asPoint().y()
                    x = f.geometry().centroid().asPoint().x()
                else:
                    r = 0  # Uses as info to separate from IMP point to grid
                    writer = QgsVectorFileWriter(self.dir_poly, "CP1250",
                                                 self.fields,
                                                 self.prov.geometryType(),
                                                 self.prov.crs(),
                                                 "ESRI shapefile")

                    if writer.hasError() != QgsVectorFileWriter.NoError:
                        self.iface.messageBar().pushMessage(
                            "Error when creating shapefile: ",
                            str(writer.hasError()))
                    writer.addFeature(feature)
                    del writer

                if self.dlg.checkBoxOnlyBuilding.isChecked(
                ):  # Only building heights
                    provider = self.dsm_build.dataProvider()
                    filePath_dsm_build = str(provider.dataSourceUri())

                    if self.imid == 1:
                        bbox = (x - r, y + r, x + r, y - r)
                        # gdalruntextdsm_build = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \
                        #                        ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \
                        #                        filePath_dsm_build + '" "' + self.plugin_dir + '/data/clipdsm.tif"'
                    else:
                        # Remove gdalwarp cuttoline with gdal.Translate. Cut to envelope of polygon feature
                        VectorDriver = ogr.GetDriverByName("ESRI Shapefile")
                        Vector = VectorDriver.Open(self.dir_poly, 0)
                        layer = Vector.GetLayer()
                        feature = layer.GetFeature(0)
                        geom = feature.GetGeometryRef()
                        minX, maxX, minY, maxY = geom.GetEnvelope()
                        bbox = (minX, maxY, maxX, minY
                                )  # Reorder bbox to use with gdal_translate
                        Vector.Destroy()
                        # gdalruntextdsm_build = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \
                        #                        ' -crop_to_cutline -of GTiff "' + filePath_dsm_build + '" "' + \
                        #                        self.plugin_dir + '/data/clipdsm.tif"'

                    # if sys.platform == 'win32':
                    #     si = subprocess.STARTUPINFO()
                    #     si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                    #     subprocess.call(gdalruntextdsm_build, startupinfo=si)
                    # else:
                    #     os.system(gdalruntextdsm_build)

                    # Remove gdalwarp with gdal.Translate
                    bigraster = gdal.Open(filePath_dsm_build)
                    gdal.Translate(self.plugin_dir + '/data/clipdsm.tif',
                                   bigraster,
                                   projWin=bbox)
                    bigraster = None

                    # os.system(gdalruntextdsm_build)
                    dataset = gdal.Open(self.plugin_dir + '/data/clipdsm.tif')
                    dsm_array = dataset.ReadAsArray().astype(np.float)
                    sizex = dsm_array.shape[0]
                    sizey = dsm_array.shape[1]
                    dem_array = np.zeros((sizex, sizey))

                else:  # Both building ground heights
                    provider = self.dsm.dataProvider()
                    filePath_dsm = str(provider.dataSourceUri())
                    provider = self.dem.dataProvider()
                    filePath_dem = str(provider.dataSourceUri())

                    # # get raster source - gdalwarp
                    if self.imid == 1:
                        bbox = (x - r, y + r, x + r, y - r)
                        # gdalruntextdsm = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \
                        #                        ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \
                        #                        filePath_dsm + '" "' + self.plugin_dir + '/data/clipdsm.tif"'
                        # gdalruntextdem = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \
                        #                        ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \
                        #                        filePath_dem + '" "' + self.plugin_dir + '/data/clipdem.tif"'
                    else:
                        # Remove gdalwarp cuttoline with gdal.Translate. Cut to envelope of polygon feature
                        VectorDriver = ogr.GetDriverByName("ESRI Shapefile")
                        Vector = VectorDriver.Open(self.dir_poly, 0)
                        layer = Vector.GetLayer()
                        feature = layer.GetFeature(0)
                        geom = feature.GetGeometryRef()
                        minX, maxX, minY, maxY = geom.GetEnvelope()
                        bbox = (minX, maxY, maxX, minY
                                )  # Reorder bbox to use with gdal_translate
                        Vector.Destroy()
                        # gdalruntextdsm = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \
                        #                  ' -crop_to_cutline -of GTiff "' + filePath_dsm + \
                        #                  '" "' + self.plugin_dir + '/data/clipdsm.tif"'
                        # gdalruntextdem = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \
                        #                  ' -crop_to_cutline -of GTiff "' + filePath_dem + \
                        #                  '" "' + self.plugin_dir + '/data/clipdem.tif"'

                    # if sys.platform == 'win32':
                    #     si = subprocess.STARTUPINFO()
                    #     si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
                    #     subprocess.call(gdalruntextdsm, startupinfo=si)
                    #     subprocess.call(gdalruntextdem, startupinfo=si)
                    # else:
                    #     os.system(gdalruntextdsm)
                    #     os.system(gdalruntextdem)

                    # Remove gdalwarp with gdal.Translate
                    bigraster = gdal.Open(filePath_dsm)
                    gdal.Translate(self.plugin_dir + '/data/clipdsm.tif',
                                   bigraster,
                                   projWin=bbox)
                    bigraster = None
                    bigraster = gdal.Open(filePath_dem)
                    gdal.Translate(self.plugin_dir + '/data/clipdem.tif',
                                   bigraster,
                                   projWin=bbox)
                    bigraster = None

                    time.sleep(0.05)
                    dataset = gdal.Open(self.plugin_dir + '/data/clipdsm.tif')
                    dsm_array = dataset.ReadAsArray().astype(np.float)
                    dataset2 = gdal.Open(self.plugin_dir + '/data/clipdem.tif')
                    dem_array = dataset2.ReadAsArray().astype(np.float)

                    if not (dsm_array.shape[0] == dem_array.shape[0]) & (
                            dsm_array.shape[1] == dem_array.shape[1]):
                        QMessageBox.critical(
                            None, "Error",
                            "All grids must be of same pixel resolution")
                        return

                geotransform = dataset.GetGeoTransform()
                scale = 1 / geotransform[1]
                nd = dataset.GetRasterBand(1).GetNoDataValue()
                nodata_test = (dsm_array == nd)
                if self.dlg.checkBoxNoData.isChecked():
                    if np.sum(dsm_array) == (dsm_array.shape[0] *
                                             dsm_array.shape[1] * nd):
                        QgsMessageLog.logMessage(
                            "Grid " + str(f.attributes()[self.idx]) +
                            " not calculated. Includes Only NoData Pixels",
                            level=QgsMessageLog.CRITICAL)
                        cal = 0
                    else:
                        dsm_array[dsm_array == nd] = np.mean(dem_array)
                        dem_array[dem_array == nd] = np.mean(dem_array)
                        cal = 1
                else:
                    if nodata_test.any():  # == True
                        QgsMessageLog.logMessage(
                            "Grid " + str(f.attributes()[self.idx]) +
                            " not calculated. Includes NoData Pixels",
                            level=QgsMessageLog.CRITICAL)
                        cal = 0
                    else:
                        cal = 1

                if cal == 1:
                    # arr = np.array([f.attributes()[self.idx], -99, -99, -99, -99, -99, -99, -99])
                    # arrmat = np.vstack([arrmat, arr])
                    # else:
                    immorphresult = imagemorphparam_v2(dsm_array, dem_array,
                                                       scale, self.imid,
                                                       self.degree, self.dlg,
                                                       imp_point)

                    zH = immorphresult["zH"]
                    fai = immorphresult["fai"]
                    pai = immorphresult["pai"]
                    zMax = immorphresult["zHmax"]
                    zSdev = immorphresult["zH_sd"]

                    zd, z0 = rg.RoughnessCalcMany(self.rm, zH, fai, pai, zMax,
                                                  zSdev)

                    # save to file
                    # header = ' Wd pai   fai   zH  zHmax   zHstd zd z0'
                    # numformat = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f'
                    arr = np.concatenate(
                        (immorphresult["deg"], immorphresult["pai"],
                         immorphresult["fai"], immorphresult["zH"],
                         immorphresult["zHmax"], immorphresult["zH_sd"], zd,
                         z0),
                        axis=1)
                    np.savetxt(self.folderPath[0] + '/' + pre + '_' +
                               'IMPGrid_anisotropic_' +
                               str(f.attributes()[self.idx]) + '.txt',
                               arr,
                               fmt=numformat,
                               delimiter=' ',
                               header=header,
                               comments='')
                    del arr

                    zHall = immorphresult["zH_all"]
                    faiall = immorphresult["fai_all"]
                    paiall = immorphresult["pai_all"]
                    zMaxall = immorphresult["zHmax_all"]
                    zSdevall = immorphresult["zH_sd_all"]
                    zdall, z0all = rg.RoughnessCalc(self.rm, zHall, faiall,
                                                    paiall, zMaxall, zSdevall)

                    # If zd and z0 are lower than open country, set to open country
                    if zdall == 0.0:
                        zdall = 0.1
                    if z0all == 0.0:
                        z0all = 0.03

                    arr2 = np.array([[
                        f.attributes()[self.idx], immorphresult["pai_all"],
                        immorphresult["fai_all"], immorphresult["zH_all"],
                        immorphresult["zHmax_all"], immorphresult["zH_sd_all"],
                        zdall, z0all
                    ]])

                    arrmat = np.vstack([arrmat, arr2])

                dataset = None
                dataset2 = None
                dataset3 = None
                self.progress.emit()

            # header2 = ' id  pai   fai   zH  zHmax   zHstd  zd  z0'
            # numformat2 = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f'
            arrmatsave = arrmat[1:arrmat.shape[0], :]
            np.savetxt(self.folderPath[0] + '/' + pre + '_' +
                       'IMPGrid_isotropic.txt',
                       arrmatsave,
                       fmt=numformat2,
                       delimiter=' ',
                       header=header2,
                       comments='')

            if self.dlg.addResultToGrid.isChecked():
                self.addattributes(self.vlayer, arrmatsave, header, pre)

            # Nas om hela loopen utforts, kan anvandas for att tilldela ret-variabeln resultatet av arbetet som ska
            # ska skickas tillbaka till image_morph_param.py
            if self.killed is False:
                self.progress.emit()
                ret = 1

        except Exception:
            # forward the exception upstream
            ret = 0
            errorstring = self.print_exception()
            #self.error.emit(e, traceback.format_exc())
            self.error.emit(errorstring)

        self.finished.emit(ret)
Beispiel #40
0
    def createGis(self) -> None:
        """
        Create TUFLOW GIS Layer(s)
        Use input GIS feature for data
        
        :return: None
        """

        if self.inputs['gis feature'] is not None:
            if self.inputs['output gis'] is not None:
                for gisOutput in self.inputs['output gis']:
                    fields = QgsFields()
                    feat = QgsFeature()
                    feat.setGeometry(self.inputs['gis feature'].geometry())
                    name = os.path.splitext(
                        os.path.basename(self.inputs['output file']))[0]
                    if gisOutput == Refh2.RF:
                        outfile = os.path.join(
                            os.path.dirname(self.inputs['output file']),
                            '2d_rf_{0}_R.shp'.format(name))
                        fields.append(
                            QgsField("Name", QVariant.String, len=100))
                        fields.append(
                            QgsField("f1", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("f2", QVariant.Double, len=15, prec=5))
                        feat.setAttributes(
                            [self.inputs['rainfall name'], 1, 1])
                    elif gisOutput == Refh2.SA_RF:
                        outfile = os.path.join(
                            os.path.dirname(self.inputs['output file']),
                            '2d_sa_rf_{0}_R.shp'.format(name))
                        fields.append(
                            QgsField("Name", QVariant.String, len=100))
                        fields.append(
                            QgsField("Catchment_",
                                     QVariant.Double,
                                     len=15,
                                     prec=5))
                        fields.append(
                            QgsField("Rain_Gauge",
                                     QVariant.Double,
                                     len=15,
                                     prec=5))
                        fields.append(
                            QgsField("IL", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("CL", QVariant.Double, len=15, prec=5))
                        feat.setAttributes([
                            self.inputs['rainfall name'], self.inputs['area'],
                            NULL, NULL, NULL
                        ])
                    elif gisOutput == Refh2.SA:
                        outfile = os.path.join(
                            os.path.dirname(self.inputs['output file']),
                            '2d_sa_{0}_R.shp'.format(name))
                        fields.append(
                            QgsField("Name", QVariant.String, len=100))
                        feat.setAttributes([self.inputs['inflow name']])
                    elif gisOutput == Refh2.BC_2d:
                        outfile = os.path.join(
                            os.path.dirname(self.inputs['output file']),
                            '2d_rf_{0}_L.shp'.format(name))
                        fields.append(QgsField("Type", QVariant.String, len=2))
                        fields.append(QgsField("Flags", QVariant.String,
                                               len=3))
                        fields.append(
                            QgsField("Name", QVariant.String, len=100))
                        fields.append(
                            QgsField("f", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("d", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("td", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("a", QVariant.Double, len=15, prec=5))
                        fields.append(
                            QgsField("b", QVariant.Double, len=15, prec=5))
                        feat.setAttributes([
                            'QT', NULL, self.inputs['inflow name'], NULL, NULL,
                            NULL, NULL, NULL
                        ])
                    elif gisOutput == Refh2.BC_1d:
                        if self.inputs[
                                'gis geometry'] == QgsWkbTypes.PointGeometry:
                            outfile = os.path.join(
                                os.path.dirname(self.inputs['output file']),
                                '1d_bc_{0}_P.shp'.format(name))
                        else:
                            outfile = os.path.join(
                                os.path.dirname(self.inputs['output file']),
                                '1d_bc_{0}_R.shp'.format(name))
                        fields.append(QgsField("Type", QVariant.String, len=2))
                        fields.append(QgsField("Flags", QVariant.String,
                                               len=6))
                        fields.append(QgsField("Name", QVariant.String,
                                               len=50))
                        fields.append(
                            QgsField("Descriptio", QVariant.String, len=250))
                        feat.setAttributes(
                            ['QT', NULL, self.inputs['inflow name'], NULL])
                    writer = QgsVectorFileWriter(outfile,
                                                 "UTF-8",
                                                 fields,
                                                 self.inputs['gis geometry'],
                                                 self.inputs['crs'],
                                                 driverName="ESRI Shapefile")
                    if writer.hasError() != QgsVectorFileWriter.NoError:
                        self.finished.emit(writer.errorMessage())
                        return
                    writer.addFeature(feat)
                    del writer
Beispiel #41
0
def _clip_vector_layer(
        layer,
        extent,
        extra_keywords=None,
        explode_flag=True,
        hard_clip_flag=False,
        explode_attribute=None):
    """Clip a Hazard or Exposure layer to the extents provided.

    The layer must be a vector layer or an exception will be thrown.

    The output layer will always be in WGS84/Geographic.

    :param layer: A valid QGIS vector or raster layer
    :type layer:

    :param extent: Either an array representing the exposure layer extents
        in the form [xmin, ymin, xmax, ymax]. It is assumed that the
        coordinates are in EPSG:4326 although currently no checks are made to
        enforce this.
        or:
        A QgsGeometry of type polygon.
        **Polygon clipping is currently only supported for vector datasets.**
    :type extent: list(float, float, float, float)

    :param extra_keywords: Optional keywords dictionary to be added to
        output layer.
    :type extra_keywords: dict

    :param explode_flag: A bool specifying whether multipart features
        should be 'exploded' into singleparts.
        **This parameter is ignored for raster layer clipping.**
    :type explode_flag: bool

    :param hard_clip_flag: A bool specifying whether line and polygon
        features that extend beyond the extents should be clipped such that
        they are reduced in size to the part of the geometry that intersects
        the extent only. Default is False.
        **This parameter is ignored for raster layer clipping.**
    :type hard_clip_flag: bool

    :param explode_attribute: A str specifying to which attribute #1,
        #2 and so on will be added in case of explode_flag being true. The
        attribute is modified only if there are at least 2 parts.
    :type explode_attribute: str

    :returns: Clipped layer (placed in the system temp dir). The output layer
        will be reprojected to EPSG:4326 if needed.
    :rtype: QgsVectorLayer

    """
    if not layer or not extent:
        message = tr('Layer or Extent passed to clip is None.')
        raise InvalidParameterError(message)

    if layer.type() != QgsMapLayer.VectorLayer:
        message = tr(
            'Expected a vector layer but received a %s.' %
            str(layer.type()))
        raise InvalidParameterError(message)

    # handle, file_name = tempfile.mkstemp('.sqlite', 'clip_',
    #    temp_dir())
    handle, file_name = tempfile.mkstemp(
        '.shp', 'clip_', temp_dir())

    # Ensure the file is deleted before we try to write to it
    # fixes windows specific issue where you get a message like this
    # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory.
    # This is because mkstemp creates the file handle and leaves
    # the file open.
    os.close(handle)
    os.remove(file_name)

    # Get the clip extents in the layer's native CRS
    geo_crs = QgsCoordinateReferenceSystem()
    geo_crs.createFromSrid(4326)
    transform = QgsCoordinateTransform(geo_crs, layer.crs())
    allowed_clip_values = [QGis.WKBPolygon, QGis.WKBPolygon25D]
    if isinstance(extent, list):
        rectangle = QgsRectangle(
            extent[0], extent[1],
            extent[2], extent[3])
        # noinspection PyCallByClass
        # noinspection PyTypeChecker
        polygon = QgsGeometry.fromRect(rectangle)
    elif (isinstance(extent, QgsGeometry) and
          extent.wkbType in allowed_clip_values):
        rectangle = extent.boundingBox().toRectF()
        polygon = extent
    else:
        raise InvalidClipGeometryError(
            tr(
                'Clip geometry must be an extent or a single part'
                'polygon based geometry.'))

    projected_extent = transform.transformBoundingBox(rectangle)

    # Get vector layer
    provider = layer.dataProvider()
    if provider is None:
        message = tr(
            'Could not obtain data provider from '
            'layer "%s"' % layer.source())
        raise Exception(message)

    # Get the layer field list, select by our extent then write to disk
    # .. todo:: FIXME - for different geometry types we should implement
    #    different clipping behaviour e.g. reject polygons that
    #    intersect the edge of the bbox. Tim
    request = QgsFeatureRequest()
    if not projected_extent.isEmpty():
        request.setFilterRect(projected_extent)
        request.setFlags(QgsFeatureRequest.ExactIntersect)

    field_list = provider.fields()

    writer = QgsVectorFileWriter(
        file_name,
        'UTF-8',
        field_list,
        layer.wkbType(),
        geo_crs,
        # 'SQLite')  # FIXME (Ole): This works but is far too slow
        'ESRI Shapefile')
    if writer.hasError() != QgsVectorFileWriter.NoError:
        message = tr(
            'Error when creating shapefile: <br>Filename:'
            '%s<br>Error: %s' %
            (file_name, writer.hasError()))
        raise Exception(message)

    # Reverse the coordinate xform now so that we can convert
    # geometries from layer crs to geocrs.
    transform = QgsCoordinateTransform(layer.crs(), geo_crs)
    # Retrieve every feature with its geometry and attributes
    count = 0
    has_multipart = False

    for feature in provider.getFeatures(request):
        geometry = feature.geometry()

        # Loop through the parts adding them to the output file
        # we write out single part features unless explode_flag is False
        if explode_flag:
            geometry_list = explode_multipart_geometry(geometry)
        else:
            geometry_list = [geometry]

        for part_index, part in enumerate(geometry_list):
            part.transform(transform)
            if hard_clip_flag:
                # Remove any dangling bits so only intersecting area is
                # kept.
                part = clip_geometry(polygon, part)
            if part is None:
                continue

            feature.setGeometry(part)
            # There are multiple parts and we want to show it in the
            # explode_attribute
            if part_index > 0 and explode_attribute is not None:
                has_multipart = True

            writer.addFeature(feature)
        count += 1
    del writer  # Flush to disk

    if count < 1:
        message = tr(
            'No features fall within the clip extents. Try panning / zooming '
            'to an area containing data and then try to run your analysis '
            'again. If hazard and exposure data doesn\'t overlap at all, it '
            'is not possible to do an analysis. Another possibility is that '
            'the layers do overlap but because they may have different '
            'spatial references, they appear to be disjointed. If this is the '
            'case, try to turn on reproject on-the-fly in QGIS.')
        raise NoFeaturesInExtentError(message)

    keyword_io = KeywordIO()
    if extra_keywords is None:
        extra_keywords = {}
    extra_keywords['had multipart polygon'] = has_multipart
    keyword_io.copy_keywords(
        layer, file_name, extra_keywords=extra_keywords)
    base_name = '%s clipped' % layer.name()
    layer = QgsVectorLayer(file_name, base_name, 'ogr')

    return layer
Beispiel #42
0
def points_along_line(layerout,
                      startpoint,
                      endpoint,
                      distance,
                      label,
                      layer,
                      selected_only=True,
                      force=False,
                      fo_fila=False,
                      divide=0,
                      decimal=2):
    """Adding Points along the line
    """

    crs = layer.crs().authid()
    # TODO check for virtual or shapelayer and set virt_layer according to it
    shape = False
    if shape:
        # define fields for feature attributes. A list of QgsField objects is needed
        fields = [QgsField("first", QVariant.Int),
                  QgsField("second", QVariant.String)]
        # create an instance of vector file writer, which will create the vector file.
        # Arguments:
        # 1. path to new file (will fail if exists already)
        # 2. encoding of the attributes
        # 3. field map
        # 4. geometry type - from WKBTYPE enum
        # 5. layer's spatial reference (instance of
        #    QgsCoordinateReferenceSystem) - optional
        # 6. driver name for the output file
        writer = QgsVectorFileWriter("my_shapes.shp",
                                     "CP1250",
                                     fields,
                                     QGis.WKBPoint,
                                     crs,
                                     "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            print "Error when creating shapefile: ", writer.hasError()
        # add a feature
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        fet.setAttributes([1, "text"])
        writer.addFeature(fet)
        # delete the writer to flush features to disk (optional)
        del writer

        layer_type = "Shapefile"  # TODO Add Shapefile functionality here
    else:
        layer_type = "memory"

    virt_layer = QgsVectorLayer("Point?crs=%s" % crs,
                                layerout,
                                layer_type)
    provider = virt_layer.dataProvider()
    virt_layer.startEditing()   # actually writes attributes
    units = layer.crs().mapUnits()
    unit_dic = {
        QGis.Degrees: 'Degrees',
        QGis.Meters: 'Meters',
        QGis.Feet: 'Feet',
        QGis.UnknownUnit: 'Unknown'}
    unit = unit_dic.get(units, 'Unknown')
    provider.addAttributes([QgsField("fid", QVariant.Int),
                            QgsField("cng_("+unit+")", QVariant.Double)])

    def get_features():
        """Getting the features
        """
        if selected_only:
            return layer.selectedFeatures()
        else:
            return layer.getFeatures()

    # Loop through all (selected) features
    for feature in get_features():
        geom = feature.geometry()
        # Add feature ID of selected feature
        fid = feature.id()
        if not geom:
            QgsMessageLog.logMessage("No geometry", "QChainage")
            continue

        features = create_points_at(startpoint,
                                    endpoint,
                                    distance,
                                    geom,
                                    fid,
                                    force,
                                    fo_fila,
                                    divide)
        provider.addFeatures(features)
        virt_layer.updateExtents()

    QgsMapLayerRegistry.instance().addMapLayers([virt_layer])
    virt_layer.commitChanges()
    virt_layer.reload()

    # from here Add labeling
    # generic labeling properties
    if label:
        virt_layer.setCustomProperty("labeling", "pal")
        virt_layer.setCustomProperty("labeling/enabled", "true")
        virt_layer.setCustomProperty("labeling/fieldName", "cng_("+unit+")")
        virt_layer.setCustomProperty("labeling/fontSize", "10")
        virt_layer.setCustomProperty("labeling/multiLineLabels", "true")
        virt_layer.setCustomProperty("labeling/formatNumbers", "true")
        virt_layer.setCustomProperty("labeling/decimals", decimal)

        # virt_layer.setCustomProperty("labeling/Size", "5")
    # symbol = QgsMarkerSymbolV2.createSimple({"name": "capital"})
    # virt_layer.setRendererV2(QgsSingleSymbolRendererV2(symbol))
    virt_layer.triggerRepaint()
    return
Beispiel #43
0
    def run_blur(self):

        self.progressBar_blur.setValue(0)
        self.label_progress.setText('')

        # Get all the fields.
        layer_to_blur = self.comboBox_layerToBlur.currentLayer()
        radius = self.spinBox_radius.value()
        display = self.checkBox_addToMap.isChecked()
        selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked()
        file_name = self.lineEdit_outputFile.text()
        export_radius = self.checkBox_exportRadius.isChecked()
        export_centroid = self.checkBox_exportCentroid.isChecked()

        if self.checkBox_envelope.isChecked():
            layer_envelope = self.comboBox_envelope.currentLayer()
        else:
            layer_envelope = None

        # Test values
        try:
            if not layer_to_blur:
                raise NoLayerProvidedException

            if not file_name and not display:
                raise NoFileNoDisplayException

            if layer_to_blur.crs().mapUnits() != 0:
                msg = tr('The projection of the map or of the layer is not '
                         'in meters. These parameters should be in meters.')
                display_message_bar(msg, level=Qgis.Warning, duration=5)
                #https://github.com/qgis/QGIS/commit/9302613f28207910608fe538a03e0bff82ca5629

            if not file_name:
                file_name = getTempFilename('blurring.shp')
                pass

            if layer_envelope:

                if layer_to_blur.crs() != layer_envelope.crs():
                    raise DifferentCrsException(
                        epsg1=layer_to_blur.crs().authid(),
                        epsg2=layer_envelope.crs().authid())

                self.label_progress.setText('Creating index ...')
                layer_envelope = LayerIndex(layer_envelope)
                self.progressBar_blur.setValue(0)

            self.label_progress.setText('Blurring ...')

            if selected_features_only:
                features = layer_to_blur.selectedFeatures()
                nb_features = layer_to_blur.selectedFeatureCount()
            else:
                features = layer_to_blur.getFeatures()
                nb_features = layer_to_blur.featureCount()

            # Fields
            fields = layer_to_blur.fields()
            if export_radius:
                fields.append(QgsField(u"Radius", QVariant.Int))
            if export_centroid:
                fields.append(QgsField(u"X centroid", QVariant.Int))
                fields.append(QgsField(u"Y centroid", QVariant.Int))

            # Creating the output shapefile
            file_writer = QgsVectorFileWriter(file_name, 'utf-8', fields,
                                              Qgis.WKBPolygon,
                                              layer_to_blur.crs(),
                                              'ESRI Shapefile')

            if file_writer.hasError() != QgsVectorFileWriter.NoError:
                raise CreatingShapeFileException(suffix=file_writer.hasError())

            # Creating the algorithm with radius
            algo = Blur(radius, layer_envelope, export_radius, export_centroid)

            for j, feature in enumerate(features):
                feature = algo.blur(feature)
                file_writer.addFeature(feature)

                # Update progress bar
                percent = int((j + 1) * 100 / nb_features)
                self.progressBar_blur.setValue(percent)

            # Write all features in the file
            del file_writer

            if display:
                old_default_projection = self.settings.value(
                    '/Projections/defaultBehaviour')
                self.settings.setValue('/Projections/defaultBehaviour',
                                       'useProject')

                layer_name = basename(file_name)
                new_layer = QgsVectorLayer(file_name, layer_name, 'ogr')
                new_layer.commitChanges()
                new_layer.clearCacheImage()
                # noinspection PyArgumentList
                QgsProject.instance().addMapLayers([new_layer])

                self.settings.setValue('/Projections/defaultBehaviour',
                                       old_default_projection)

            msg = tr('Successful export in %s' % file_name)
            iface.messageBar().pushMessage(msg, level=Qgis.Info, duration=5)

            self.signalAskCloseWindow.emit()

        except GeoPublicHealthException as e:
            self.label_progress.setText('')
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)

        finally:
            # noinspection PyArgumentList
            QApplication.restoreOverrideCursor()
            # noinspection PyArgumentList
            QApplication.processEvents()
Beispiel #44
0
    def run(self):
        """Run method that performs all the real work"""

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.

            filename = os.path.abspath("Sample_Data/sample_data.shp")
            iface.messageBar().pushMessage("Shapefile loaded ...",
                                           QgsMessageBar.INFO)

            source_layer = iface.addVectorLayer(filename, "sample_data", "ogr")
            centroid = QgsVectorLayer('Point', 'Centroid', 'memory')

            fields = QgsFields()
            fields.append(QgsField("code", QVariant.String))
            fields.append(QgsField("x", QVariant.Double))
            fields.append(QgsField("y", QVariant.Double))

            # Define additional attributes already on the layer level
            centroid_layer = QgsVectorFileWriter(
                centroid, "UTF8", fields, QGis.WKBPoint,
                QgsCoordinateReferenceSystem(4326), "ESRI Shapefile")

            if centroid_layer.hasError() != QgsVectorFileWriter.NoError:
                print("Error when creating centroid: ",
                      centroid_layer.errorMessage())
                iface.messageBar().pushMessage("Feature addition failed.",
                                               QgsMessageBar.CRITICAL)

            centroid_layer.startEditing()
            # Loop over all features
            for source_feature in source_layer.getFeatures():
                geometry = source_feature.geometry()
                centroid = geometry.centroid().asPoint()
                pts = [Centroid]
                name = source_feature["code"]

                # Create the new feature with the fields of the ogr layer
                # And set geometry and attribute before adding it to the target layer
                centroid_feature = QgsFeature(source_layer.fields())
                centroid_feature = source_feature.attributes()
                centroid_feature.setAttributes(centroid_feature)
                centroid_feature.setGeometry(centroid)
                centroid_feature['code'] = name
                centroid_layer.addFeature(centroid_feature)

                # Loop centroids to shapefile
                for x, y in pts:
                    centroid_feature = QgsFeature()
                    point = QgsPoint(x, y)
                    centroid_feature.setGeometry(QgsGeometry.fromPoint(point))
                    centroid_feature.setAttributes(attrs)
                    prov.addFeatures([centroid_feature])

            centroid_layer.commitChanges()

            # Add the layer to the registry
            QgsMapLayerRegistry.instance().addMapLayer(centroid_layer)

            # Save centroid layer as csv format
            QgsVectorFileWriter.writeAsVectorFormat(
                centroid_layer,
                r'extract_centroid',
                "utf-8",
                None,
                "CSV",
                layerOptions='GEOMETRY=AS_XYZ')
            iface.messageBar().pushMessage("Extract centroid saved as csv ...",
                                           QgsMessageBar.INFO)
    def run_blur(self):

        self.progressBar_blur.setValue(0)
        self.label_progress.setText('')

        # Get all the fields.
        layer_to_blur = self.comboBox_layerToBlur.currentLayer()
        radius = self.spinBox_radius.value()
        display = self.checkBox_addToMap.isChecked()
        selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked()
        file_name = self.lineEdit_outputFile.text()
        export_radius = self.checkBox_exportRadius.isChecked()
        export_centroid = self.checkBox_exportCentroid.isChecked()

        if self.checkBox_envelope.isChecked():
            layer_envelope = self.comboBox_envelope.currentLayer()
        else:
            layer_envelope = None

        # Test values
        try:
            if not layer_to_blur:
                raise NoLayerProvidedException

            if not file_name and not display:
                raise NoFileNoDisplayException

            if layer_to_blur.crs().mapUnits() != 0:
                msg = tr('The projection of the map or of the layer is not '
                            'in meters. These parameters should be in meters.')
                display_message_bar(
                    msg, level=QgsMessageBar.WARNING, duration=5)

            if not file_name:
                file_name = getTempFilenameInTempFolder('blurring.shp')
                pass

            if layer_envelope:

                if layer_to_blur.crs() != layer_envelope.crs():
                    raise DifferentCrsException(
                        epsg1=layer_to_blur.crs().authid(),
                        epsg2=layer_envelope.crs().authid())

                self.label_progress.setText('Creating index ...')
                layer_envelope = LayerIndex(layer_envelope)
                self.progressBar_blur.setValue(0)

            self.label_progress.setText('Blurring ...')

            if selected_features_only:
                features = layer_to_blur.selectedFeatures()
                nb_features = layer_to_blur.selectedFeatureCount()
            else:
                features = layer_to_blur.getFeatures()
                nb_features = layer_to_blur.featureCount()

            # Fields
            fields = layer_to_blur.pendingFields()
            if export_radius:
                fields.append(QgsField(u"Radius", QVariant.Int))
            if export_centroid:
                fields.append(QgsField(u"X centroid", QVariant.Int))
                fields.append(QgsField(u"Y centroid", QVariant.Int))

            # Creating the output shapefile
            file_writer = QgsVectorFileWriter(
                file_name,
                'utf-8',
                fields,
                QGis.WKBPolygon,
                layer_to_blur.crs(),
                'ESRI Shapefile')

            if file_writer.hasError() != QgsVectorFileWriter.NoError:
                raise CreatingShapeFileException(suffix=file_writer.hasError())

            # Creating the algorithm with radius
            algo = Blur(radius, layer_envelope, export_radius, export_centroid)

            for j, feature in enumerate(features):
                feature = algo.blur(feature)
                file_writer.addFeature(feature)

                # Update progress bar
                percent = int((j + 1) * 100 / nb_features)
                self.progressBar_blur.setValue(percent)

            # Write all features in the file
            del file_writer

            if display:
                old_default_projection = self.settings.value(
                    '/Projections/defaultBehaviour')
                self.settings.setValue(
                    '/Projections/defaultBehaviour', 'useProject')

                layer_name = basename(file_name)
                new_layer = QgsVectorLayer(file_name, layer_name, 'ogr')
                new_layer.commitChanges()
                new_layer.clearCacheImage()
                # noinspection PyArgumentList
                QgsMapLayerRegistry.instance().addMapLayers([new_layer])

                self.settings.setValue(
                    '/Projections/defaultBehaviour', old_default_projection)

            msg = tr('Successful export in %s' % file_name)
            iface.messageBar().pushMessage(
                msg, level=QgsMessageBar.INFO, duration=5)

            self.signalAskCloseWindow.emit()

        except GeoPublicHealthException, e:
            self.label_progress.setText('')
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)