def createShapeFileLayer(path, name, srid, attributes, types, geometrytype): # create new layer with given attributes # todo: created table has no attributes. not used # use createShapeFileFullLayer instead filename = path + "/" + name + ".shp" # create the required fields fields = QgsFields() for i, attr in enumerate(attributes): fields.append(QgsField(attr, types[i])) # create an instance of vector file writer, which will create the vector file. writer = None options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = 'utf-8' if 'point' in geometrytype.lower(): writer = QgsVectorFileWriter.create(filename, fields, QgsWkbTypes.Point, srid, QgsCoordinateTransformContext(), options) elif 'line' in geometrytype.lower(): writer = QgsVectorFileWriter.create(filename, fields, QgsWkbTypes.LineString, srid, QgsCoordinateTransformContext(), options) elif 'polygon' in geometrytype.lower(): writer = QgsVectorFileWriter.create(filename, fields, QgsWkbTypes.Polygon, srid, QgsCoordinateTransformContext(), options) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) return None # delete the writer to flush features to disk (optional) del writer # open the newly created file vlayer = QgsVectorLayer(filename, name, "ogr") if not vlayer.isValid(): print("Layer failed to open!") return None return vlayer
def get_writer(name, crs, fields=QgsFields(), geom_type=WKBMultiPolygon): transform_context = QgsProject.instance().transformContext() save_options = QgsVectorFileWriter.SaveVectorOptions() save_options.driverName = "ESRI Shapefile" save_options.fileEncoding = "UTF-8" return QgsVectorFileWriter.create(name, fields, geom_type, crs, transform_context, save_options)
def copyLayerToShapeFile(layer, path, name): # Get layer provider provider = layer.dataProvider() filename = path + "/" + name + ".shp" fields = provider.fields() if layer.isSpatial(): geometry = layer.wkbType() else: geometry = None srid = layer.crs() # create an instance of vector file writer, which will create the vector file. options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = 'utf-8' writer = QgsVectorFileWriter.create(filename, fields, geometry, srid, QgsCoordinateTransformContext(), options) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) return None # add features by iterating the values for feat in layer.getFeatures(): writer.addFeature(feat) # delete the writer to flush features to disk del writer # open the newly created file vlayer = QgsVectorLayer(filename, name, "ogr") if not vlayer.isValid(): print("Layer failed to load!") return None return vlayer
def to_layer(fields, crs, encoding, geom_type, layer_type, path): layer = None if layer_type == 'memory': layer = QgsVectorLayer(geom_type + '?crs=' + crs.authid(), path, "memory") pr = layer.dataProvider() pr.addAttributes(fields.toList()) layer.updateFields() elif layer_type == 'shapefile': wkbTypes = {'Point': QgsWkbTypes.Point, 'Linestring': QgsWkbTypes.LineString, 'Polygon': QgsWkbTypes.Polygon} options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = encoding file_writer = QgsVectorFileWriter.create(path, fields, wkbTypes[geom_type], crs, QgsCoordinateTransformContext(), options) if file_writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", file_writer.errorMessage()) del file_writer layer = QgsVectorLayer(path, ntpath.basename(path)[:-4], "ogr") elif layer_type == 'postgis': # this is needed to load the table later # uri = connstring + """ type=""" + geom_types[geom_type] + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ connstring, schema_name, table_name = path uri = connstring + """ type=""" + geom_type + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ crs_id = crs.postgisSrid() try: con = psycopg2.connect(connstring) cur = con.cursor() create_query = cur.mogrify( """DROP TABLE IF EXISTS "%s"."%s"; CREATE TABLE "%s"."%s"( geom geometry(%s, %s))""", ( AsIs(schema_name), AsIs(table_name), AsIs(schema_name), AsIs(table_name), geom_type, AsIs(crs_id))) cur.execute(create_query) con.commit() post_q_flds = {2: 'bigint', 6: 'numeric', 1: 'bool', 'else': 'text', 4: 'numeric'} for f in fields: f_type = f.type() if f_type not in [2, 6, 1]: f_type = 'else' attr_query = cur.mogrify("""ALTER TABLE "%s"."%s" ADD COLUMN "%s" %s""", ( AsIs(schema_name), AsIs(table_name), AsIs(f.name()), AsIs(post_q_flds[f_type]))) cur.execute(attr_query) con.commit() layer = QgsVectorLayer(uri, table_name, 'postgres') except psycopg2.DatabaseError as e: print(e) return layer
def save_as_dbf(self, raster_source) -> bool: """Save/export a copy of the RAT to path""" # Add .VAT: .DBF is added by the exporter if not raster_source.upper().endswith('.VAT'): raster_source = raster_source + '.vat' options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'ESRI Shapefile' options.layerOptions = ['SHPT=NULL'] writer = QgsVectorFileWriter.create( raster_source, self.qgis_fields(), QgsWkbTypes.Unknown, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), options) self.path = raster_source + '.dbf' rat_log('RAT saved as DBF for layer %s' % raster_source) return writer.addFeatures(self.qgis_features())
def to_layer(features, crs, encoding, geom_type, layer_type, path): first_feat = features[0] fields = first_feat.fields() layer = None if layer_type == 'memory': layer = QgsVectorLayer(geom_type + '?crs=' + crs.authid(), path, "memory") pr = layer.dataProvider() pr.addAttributes(fields.toList()) layer.updateFields() layer.startEditing() pr.addFeatures(features) layer.commitChanges() elif layer_type == 'shapefile': wkbTypes = { 'Point': QgsWkbTypes.Point, 'Linestring': QgsWkbTypes.LineString, 'Polygon': QgsWkbTypes.Polygon } options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = encoding file_writer = QgsVectorFileWriter.create( path, fields, wkbTypes[geom_type], crs, QgsCoordinateTransformContext(), options) if file_writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", file_writer.errorMessage()) del file_writer layer = QgsVectorLayer(path, ntpath.basename(path)[:-4], "ogr") pr = layer.dataProvider() layer.startEditing() pr.addFeatures(features) layer.commitChanges() elif layer_type == 'postgis': # this is needed to load the table later # uri = connstring + """ type=""" + geom_types[geom_type] + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ connstring, schema_name, table_name = path uri = connstring + """ type=""" + geom_type + """ table=\"""" + schema_name + """\".\"""" + table_name + """\" (geom) """ crs_id = crs.postgisSrid() try: con = psycopg2.connect(connstring) cur = con.cursor() create_query = cur.mogrify( """DROP TABLE IF EXISTS "%s"."%s"; CREATE TABLE "%s"."%s"( geom geometry(%s, %s))""", (AsIs(schema_name), AsIs(table_name), AsIs(schema_name), AsIs(table_name), geom_type, AsIs(crs_id))) cur.execute(create_query) con.commit() post_q_flds = { 2: 'bigint', 6: 'numeric', 1: 'bool', 'else': 'text', 4: 'numeric' } for f in fields: f_type = f.type() if f_type not in [2, 6, 1]: f_type = 'else' attr_query = cur.mogrify( """ALTER TABLE "%s"."%s" ADD COLUMN "%s" %s""", (AsIs(schema_name), AsIs(table_name), AsIs( f.name()), AsIs(post_q_flds[f_type]))) cur.execute(attr_query) con.commit() field_names = ",".join(['"' + f.name() + '"' for f in fields]) for feature in features: attrs = [i if i else None for i in feature.attributes()] insert_query = cur.mogrify( """INSERT INTO "%s"."%s" (%s, geom) VALUES %s, ST_GeomFromText(%s,%s))""", (AsIs(schema_name), AsIs(table_name), AsIs(field_names), tuple(attrs), feature.geometry().asWkt(), AsIs(crs_id))) idx = insert_query.find(b', ST_GeomFromText') - 1 insert_query = insert_query[:idx] + insert_query[(idx + 1):] cur.execute(insert_query) con.commit() pkey_query = cur.mogrify( """ALTER TABLE "%s"."%s" DROP COLUMN IF EXISTS seg_id; ALTER TABLE "%s"."%s" ADD COLUMN seg_id serial PRIMARY KEY NOT NULL;""", (AsIs(schema_name), AsIs(table_name), AsIs(schema_name), AsIs(table_name))) cur.execute(pkey_query) con.commit() con.close() layer = QgsVectorLayer(uri, table_name, 'postgres') except psycopg2.DatabaseError as e: # fix_print_with_import print(e) return layer
def create_shapefile_full_layer_data_provider(path, name, srid, attributes, types, values, coords): """ Creates a shapefile using the Shapefile Data Provider Parameters ---------- path : `str` folder where the shapefile is to be saved name : `str` name of the shapefile srid : `str` CRS of the newly created shapefile attributes: array_like list of attribute (field) names types : array_like list of types (field) types, in sync with the `attributes` parameter values : array_like coordinates and attribute data, one array for each feature (F, C + A), F for features, C for coordinates and A for attribute data coords : array_like indices of the coordinate values within the `values` array Returns ------- vl : `QgsVectorLayer` the newly-created layer """ # create new layer with given attributes filename = path + "/" + name + ".shp" # create an instance of vector file writer, which will create the vector file. writer = None options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = "ESRI Shapefile" options.fileEncoding = 'utf-8' if len(coords) == 2: type = 'point' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.Point, srid, QgsCoordinateTransformContext(), options) elif len(coords) == 4: type = 'line' writer = QgsVectorFileWriter.create(filename, QgsFields(), QgsWkbTypes.LineString, srid, QgsCoordinateTransformContext(), options) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) return None del writer # open the newly created file vl = QgsVectorLayer(filename, name, "ogr") pr = vl.dataProvider() # create the required fields for i, attr in enumerate(attributes): pr.addAttributes([QgsField(attr, types[i])]) vl.commitChanges() # add features by iterating the values feat = QgsFeature() for i, val in enumerate(values): # add geometry try: if type == 'point': geometry = QgsGeometry.fromPoint([QgsPoint(float(val[coords[0]]), float(val[coords[1]]))]) elif type == 'line': geometry = QgsGeometry.fromPolyline([QgsPoint(float(val[coords[0]]), float(val[coords[1]])), QgsPoint(float(val[coords[2]]), float(val[coords[3]]))]) feat.setGeometry(geometry) except: pass # add attributes attrs = [] for j, attr in enumerate(attributes): attrs.append(val[j]) feat.setAttributes(attrs) pr.addFeature(feat) vl.updateExtents() vl = QgsVectorLayer(filename, name, "ogr") if not vl.isValid(): raise IOError("Layer could not be created") return None return vl
layer = QgsVectorLayer(str(path_data)) crs: QgsCoordinateReferenceSystem = layer.crs() print(crs) if crs.isGeographic(): raise TypeError("Cannot process data with geographic coordinate system.") fields: QgsFields = layer.fields() save_options = QgsVectorFileWriter.SaveVectorOptions() save_options.fileEncoding = "UTF-8" writer: QgsVectorFileWriter = QgsVectorFileWriter.create( str(path_data_output), fields, QgsWkbTypes.Point, layer.crs(), QgsCoordinateTransformContext(), save_options) features: QgsFeatureIterator = layer.getFeatures() feature: QgsFeature for feature in features: new_feature = QgsFeature(fields) old_geom: QgsGeometry = feature.geometry() new_geom: QgsGeometry = old_geom.poleOfInaccessibility(precision)[0] new_feature.setAttributes(feature.attributes())