def ogr_basic_9(): geom_type_tuples = [ [ ogr.wkbUnknown, "Unknown (any)" ], [ ogr.wkbPoint, "Point" ], [ ogr.wkbLineString, "Line String"], [ ogr.wkbPolygon, "Polygon"], [ ogr.wkbMultiPoint, "Multi Point"], [ ogr.wkbMultiLineString, "Multi Line String"], [ ogr.wkbMultiPolygon, "Multi Polygon"], [ ogr.wkbGeometryCollection, "Geometry Collection"], [ ogr.wkbNone, "None"], [ ogr.wkbUnknown | ogr.wkb25DBit, "3D Unknown (any)" ], [ ogr.wkbPoint25D, "3D Point" ], [ ogr.wkbLineString25D, "3D Line String"], [ ogr.wkbPolygon25D, "3D Polygon"], [ ogr.wkbMultiPoint25D, "3D Multi Point"], [ ogr.wkbMultiLineString25D, "3D Multi Line String"], [ ogr.wkbMultiPolygon25D, "3D Multi Polygon"], [ ogr.wkbGeometryCollection25D, "3D Geometry Collection"], [ 123456, "Unrecognised: 123456" ] ] for geom_type_tuple in geom_type_tuples: if ogr.GeometryTypeToName(geom_type_tuple[0]) != geom_type_tuple[1]: gdaltest.post_reason('fail') print('Got %s, expected %s' % (ogr.GeometryTypeToName(geom_type_tuple[0]), geom_type_tuple[1])) return 'fail' return 'success'
def get_datasource_information(datasource, print_results=False): """Get informations about the first layer in the datasource. :param datasource: An OGR datasource. :param bool print_results: True to print the results on the screen. """ info = {} layer = datasource.GetLayerByIndex(0) bbox = layer.GetExtent() info['bbox'] = dict(xmin=bbox[0], xmax=bbox[1], ymin=bbox[2], ymax=bbox[3]) srs = layer.GetSpatialRef() if srs: info['epsg'] = srs.GetAttrValue('authority', 1) else: info['epsg'] = 'not available' info['type'] = ogr.GeometryTypeToName(layer.GetGeomType()) # Gets the attributes names. info['attributes'] = [] layer_definition = layer.GetLayerDefn() for index in range(layer_definition.GetFieldCount()): info['attributes'].append( layer_definition.GetFieldDefn(index).GetName()) # Print the results. if print_results: pprint(info) return info
def read_ogr_features(layer): """Convert OGR features from a layer into dictionaries. :param layer: OGR layer. """ features = [] layer_defn = layer.GetLayerDefn() layer.ResetReading() type = ogr.GeometryTypeToName(layer.GetGeomType()) for item in layer: attributes = {} for index in range(layer_defn.GetFieldCount()): field_defn = layer_defn.GetFieldDefn(index) key = field_defn.GetName() value = item.GetFieldAsString(index) attributes[key] = value feature = { "type": "Feature", "geometry": { "type": type, "coordinates": item.GetGeometryRef().ExportToWkt() }, "properties": attributes } features.append(feature) return features
def geometry_fields_schema(self): # some layers have multiple geometric feature types # most of the time, it should only have one though return [(self.layer_defn.GetGeomFieldDefn(i).GetName(), # some times the name doesn't appear # but the type codes are well defined ogr.GeometryTypeToName( self.layer_defn.GetGeomFieldDefn(i).GetType()), self.layer_defn.GetGeomFieldDefn(i).GetType()) \ for i in range(self.layer_defn.GetGeomFieldCount())]
def ReportOnLayer(self, poLayer, pszWHERE=None, poSpatialFilter=None): bVerbose = True poDefn = poLayer.GetLayerDefn() #/* -------------------------------------------------------------------- */ #/* Set filters if provided. */ #/* -------------------------------------------------------------------- */ if pszWHERE is not None: if poLayer.SetAttributeFilter(pszWHERE) != 0: self.out("FAILURE: SetAttributeFilter(%s) failed." % pszWHERE) return if poSpatialFilter is not None: poLayer.SetSpatialFilter(poSpatialFilter) #/* -------------------------------------------------------------------- */ #/* Report various overall information. */ #/* -------------------------------------------------------------------- */ self.out("") self.out("Layer name: %s" % poDefn.GetName()) if bVerbose: self.out("Geometry: %s" % ogr.GeometryTypeToName(poDefn.GetGeomType())) self.out("Feature Count: %d" % poLayer.GetFeatureCount()) oExt = poLayer.GetExtent(True, can_return_null=True) if oExt is not None: self.out("Extent: (%f, %f) - (%f, %f)" % (oExt[0], oExt[1], oExt[2], oExt[3])) if poLayer.GetSpatialRef() is None: pszWKT = "(unknown)" else: pszWKT = poLayer.GetSpatialRef().ExportToPrettyWkt() self.out("Layer SRS WKT:\n%s" % pszWKT) if len(poLayer.GetFIDColumn()) > 0: self.out("FID Column = %s" % poLayer.GetFIDColumn()) if len(poLayer.GetGeometryColumn()) > 0: self.out("Geometry Column = %s" % poLayer.GetGeometryColumn()) for iAttr in range(poDefn.GetFieldCount()): poField = poDefn.GetFieldDefn(iAttr) self.out( "%s: %s (%d.%d)" % ( \ poField.GetNameRef(), \ poField.GetFieldTypeName( poField.GetType() ), \ poField.GetWidth(), \ poField.GetPrecision() ))
def get_layer_info(layer): metadata = {} extent = layer.GetExtent() crs = layer.GetSpatialRef().ExportToProj4() bounds = {'left': extent[0], 'right': extent[1], 'bottom': extent[2], 'top': extent[3]} metadata['crs'] = crs metadata['nativeBounds'] = bounds metadata['type_'] = 'vector' metadata['bounds'] = from_bounds_to_geojson(bounds, crs) metadata['featureCount'] = layer.GetFeatureCount() definition = layer.GetLayerDefn() count = definition.GetFieldCount() metadata['geomType'] = ogr.GeometryTypeToName(definition.GetGeomType()) metadata['layerFields'] = [get_field_info(definition.GetFieldDefn(i)) for i in range(count)] return metadata
#verify the file was opened, exit if not if dataSource is None: print 'Failed to open file' sys.exit(1) #get the first (and only) data layer layer = dataSource.GetLayer(0) layerName = layer.GetName() layerType = layer.GetGeomType() layerExtent = layer.GetExtent() print "SpatialRef: ", layer.GetSpatialRef() #convert integer layertype to text equiv layerTypeS = ogr.GeometryTypeToName(layerType) print 'Layer', layerName, 'is a', layerTypeS, 'layer with bounding box:' print layerExtent, '\n' #get access to the layer's non-spatial info: number of fields, #field names, types, etc. featureDefn = layer.GetLayerDefn() fieldCount = featureDefn.GetFieldCount() print "The layer's feature definition has the following", fieldCount, "fields:" feat = layer.GetFeature(0) print "feature is ", feat
def __init__(self, layer, source): self.gpkg_layer = layer self.layer_defn = self.gpkg_layer.GetLayerDefn() self.geometry_type = self.gpkg_layer.GetGeomType() self.geometry_type_name = ogr.GeometryTypeToName(self.geometry_type) self.source = source
dataSource = None #set filename and open Parcels.shp filename2 = (dataDir + "Parcels.shp") dataSource2 = driver.Open(filename2, gdalconst.GA_ReadOnly) #if no file, exit if dataSource2 is None: print('Failed to open file') sys.exit(1) #assign variables for layer, name, geometry type ParcelsLayer = dataSource2.GetLayer(0) ParcelsName = ParcelsLayer.GetName() ParcelsType = ParcelsLayer.GetGeomType() ParcelsTypeS = ogr.GeometryTypeToName(ParcelsType) print('Layer', ParcelsName, 'is a', ParcelsTypeS) #assign variables for featureDefn, fieldCount featureDefn = ParcelsLayer.GetLayerDefn() fieldCount = featureDefn.GetFieldCount() print("The layer's feature definition has the following", fieldCount, "fields:") #loop through fields and assign variables for feature columns for i in range(fieldCount): fieldDef = featureDefn.GetFieldDefn(i) fldName = fieldDef.GetNameRef() fldWidth = fieldDef.GetWidth()
def read_shapefile(filename): """ Reads lat / lon from a ESRI shape file. Paramters ---------- filename: filename of ESRI shape file. Returns ------- lat, lon: array_like coordinates """ import ogr import osr driver = ogr.GetDriverByName("ESRI Shapefile") data_source = driver.Open(filename, 0) layer = data_source.GetLayer(0) layer_type = ogr.GeometryTypeToName(layer.GetGeomType()) srs = layer.GetSpatialRef() if not srs.IsGeographic(): print(("""Spatial Reference System in % s is not latlon. Converting.""" % filename)) # Create spatialReference, EPSG 4326 (lonlat) srs_geo = osr.SpatialReference() srs_geo.ImportFromEPSG(4326) cnt = layer.GetFeatureCount() profiles = [] if layer_type == "Point": lon = [] lat = [] for pt in range(0, cnt): feature = layer.GetFeature(pt) try: id = feature.id except: id = str(pt) try: name = feature.name except: name = str(pt) try: flightline = feature.flightline except: flightline = 2 try: glaciertype = feature.gtype except: glaciertype = 4 try: flowtype = feature.ftype except: flowtype = 2 geometry = feature.GetGeometryRef() # Transform to latlon if needed if not srs.IsGeographic(): geometry.TransformTo(srs_geo) point = geometry.GetPoint() lon.append(point[0]) lat.append(point[1]) try: clon = feature.clon except: clon = point[0] try: clat = feature.clat except: clat = point[1] profiles.append([point[1], point[0], id, name, clat, clon, flightline, glaciertype, flowtype]) elif layer_type in ("Line String", "Multi Line String"): for pt in range(0, cnt): feature = layer.GetFeature(pt) try: id = feature.id except: id = str(pt) if id is None: id = str(pt) try: name = feature.name except: name = str(pt) try: clon = feature.clon except: clon = 0.0 try: clat = feature.clat except: clat = 0.0 try: flightline = feature.flightline except: flightline = 2 if flightline is None: flightline = 2 try: glaciertype = feature.gtype except: glaciertype = 4 if glaciertype is None: glaciertype = 4 try: flowtype = feature.ftype except: flowtype = 2 if flowtype is None: flowtype = 2 geometry = feature.GetGeometryRef() # Transform to latlon if needed if not srs.IsGeographic(): geometry.TransformTo(srs_geo) lon = [] lat = [] for i in range(0, geometry.GetPointCount()): # GetPoint returns a tuple not a Geometry pt = geometry.GetPoint(i) lon.append(pt[0]) lat.append(pt[1]) # skip features with less than 2 points: if len(lat) > 1: profiles.append([lat, lon, id, name, clat, clon, flightline, glaciertype, flowtype]) else: raise NotImplementedError("Geometry type '{0}' is not supported".format(layer_type)) return profiles
#store layer info layer_info = {} layer_table = {} if layer_num > 0: for i in range(layer_num): #get shapefile layer layer = shp_datasource.GetLayerByIndex(i) #get layer name layer_name = layer.GetName() layer_info['name'] = layer_name #get layer type geom_type = layer.GetGeomType() #convert layer type to geometry name geom_name = ogr.GeometryTypeToName(geom_type) layer_info['geometry'] = geom_name #get number of features in layer num_feature = layer.GetFeatureCount() layer_info['number of features'] = num_feature #get layer extent layer_extent = layer.GetExtent() layer_info['extent'] = layer_extent #get layer spatial reference (projection info) layer_spatial_ref = layer.GetSpatialRef() spatial_ref_name = layer_spatial_ref.ExportToWkt() layer_info['spatial reference'] = spatial_ref_name #get layer unit layer_unit = layer_spatial_ref.GetLinearUnitsName() layer_info['unit'] = layer_unit #get layer number of columns in shp attribute table
for f in fileNames: if f.endswith('.shp'): print ('Filename: ' + f) f = os.path.join(dirName, f) ds = ogr.Open(f) for lyr in ds: dateStamp = datetime.now().strftime("%Y-%m-%dT%H:%M:%S") print ('DateStamp: ' + dateStamp) fileSize = sum([sum(map(lambda fname: os.path.getsize(os.path.join(directory, fname)), files)) for directory, folders, files in os.walk(dirName)]) fileSize = float(fileSize) fileSize = fileSize/1000/1000 fileSize = numpy.around(fileSize, decimals=1) fileSize = str(fileSize) print ('Filesize: ' + fileSize + ' MB') (minx, maxx, miny, maxy) = lyr.GetExtent() print("Geometry type: %s" % ogr.GeometryTypeToName(lyr.GetGeomType())) geomType = ogr.GeometryTypeToName(lyr.GetGeomType()) srs = lyr.GetSpatialRef() srsAuth = srs.GetAttrValue("AUTHORITY",0) srsCode = srs.GetAttrValue("AUTHORITY",1) print ('Projection: '+ srsAuth + ' ' + srsCode) print ('Extent: %f, %f - %f %f' % (minx, miny, maxx, maxy)) #W-S-E-N print("Feature count: %d" % lyr.GetFeatureCount()) lyr_defn = lyr.GetLayerDefn() for i in range(lyr_defn.GetFieldCount()): field_defn = lyr_defn.GetFieldDefn(i) name = field_defn.GetName() ftype = ogr.GetFieldTypeName(field_defn.GetType()) width = field_defn.GetWidth() prec = field_defn.GetPrecision() print('Field: %s %s (%d.%d)' % (name, ftype, width, prec))
print('DateStamp: ' + dateStamp) fileSize = sum([ sum( map( lambda fname: os.path.getsize( os.path.join(directory, fname)), files)) for directory, folders, files in os.walk(dirName) ]) fileSize = float(fileSize) fileSize = fileSize / 1000 / 1000 fileSize = numpy.around(fileSize, decimals=1) fileSize = str(fileSize) print('Filesize: ' + fileSize + ' MB') (minx, maxx, miny, maxy) = lyr.GetExtent() print("Geometry type: %s" % ogr.GeometryTypeToName(lyr.GetGeomType())) geomType = ogr.GeometryTypeToName(lyr.GetGeomType()) srs = lyr.GetSpatialRef() srsAuth = srs.GetAttrValue("AUTHORITY", 0) srsCode = srs.GetAttrValue("AUTHORITY", 1) print('Projection: ' + srsAuth + ' ' + srsCode) print('Extent: %f, %f - %f %f' % (minx, miny, maxx, maxy)) #W-S-E-N print("Feature count: %d" % lyr.GetFeatureCount()) lyr_defn = lyr.GetLayerDefn() for i in range(lyr_defn.GetFieldCount()): field_defn = lyr_defn.GetFieldDefn(i) name = field_defn.GetName() ftype = ogr.GetFieldTypeName(field_defn.GetType()) width = field_defn.GetWidth() prec = field_defn.GetPrecision()
def readMetadata(self): """Regresa un diccionario con la información leida de la fuente de datos. vector_info['feature_count'] --> La cantidad de features. vector_info['prj_info'] --> (epsg code,pretty wkt) Información de la proyeccion. vector_info['prj_dict'] --> diccionario con la información de proyección organizada para meterla en el iso_xml vector_info['field_count'] --> número de campos. vector_info['att_info'] --> Diccionario. Para cada nombre de atributo: Diccionario {'tipo':f_type,'descripcion':''}. vector_info['bbox'] --> Lista con las coordenadas del extent (xmin,ymax,xmax,ymin). vector_info['bbox_wkt'] --> el wkt del polígono nque representa la extensión de la capa """ if self.shp_path is not None: driver = ogr.GetDriverByName('ESRI Shapefile') shape = driver.Open(self.shp_path, 0) if shape is not None: self.capa = shape.GetLayer() else: raise InvalidFormatError('No se pudo leer el archivo') if self.postgis_conn is not None: connString = "PG: host="+self.postgis_conn['url']+ " dbname=" + self.postgis_conn['bd'] + " user="******" password="******"nombre")) return vector_info
def fix_vector_layer(in_layer, layer_name="", epsg=3857, in_spatial_ref=None): """ This function standardizes a vector layer: 1. Multipart to singleparts 2. 3D polygon to 2D polygon 3. Reprojection 4. Fix for self intersections INPUT: layer, layer_name OUTPUT: out_datasource, layer_name """ # retrieving lost features lost_features = [] in_feature_count = in_layer.GetFeatureCount() # Get inspatial reference and geometry from in shape geom_type = in_layer.GetGeomType() if in_spatial_ref is None: in_spatial_ref = in_layer.GetSpatialRef() in_layer.ResetReading() layer_name = layer_name.lower() layer_name = fix_layer_name_length(layer_name) # Create output dataset and force dataset to multiparts # variable output_geom_type, does it always work? if not add check geom_name = ogr.GeometryTypeToName(geom_type) if "polygon" in geom_name.lower(): output_geom_type = 3 # polygon elif "line" in geom_name.lower(): output_geom_type = 2 # linestring elif "point" in geom_name.lower(): output_geom_type = 1 # point else: logger.error("Geometry could not be translated to singlepart %s" % geom_name) raise TypeError() # create memory datasource for mem_datasource = create_mem_ds() mem_layer = mem_datasource.CreateLayer(layer_name, in_spatial_ref, output_geom_type) # create datasource output out_datasource = create_mem_ds() spatial_ref_out = osr.SpatialReference() spatial_ref_out.ImportFromEPSG(int(epsg)) out_layer = out_datasource.CreateLayer(layer_name, spatial_ref_out, output_geom_type) layer_defn = in_layer.GetLayerDefn() for i in range(layer_defn.GetFieldCount()): field_defn = layer_defn.GetFieldDefn(i) mem_layer.CreateField(field_defn) logger.info("check - Multipart to singlepart") mem_layer, additional_lost_features = transform_multipart_to_singlepart( in_layer, mem_layer) lost_features = lost_features + additional_lost_features if mem_layer.GetFeatureCount() == 0: logger.warning("Multipart to singlepart failed") raise TypeError() flatten = False if "3D" in geom_name: logger.warning("geom type: " + geom_name) logger.info("Flattening to 2D") flatten = True elif geom_type <= 0: logger.error("Geometry invalid, please fix it first, type is: %s" % geom_name) raise TypeError() # Copy fields from memory layer to output dataset layer_defn = in_layer.GetLayerDefn() for i in range(layer_defn.GetFieldCount()): out_layer.CreateField(layer_defn.GetFieldDefn(i)) logger.info("check - Reproject layer to {}".format(str(epsg))) reproject = osr.CoordinateTransformation(in_spatial_ref, spatial_ref_out) for out_feat in mem_layer: out_geom = out_feat.GetGeometryRef() out_geom, valid = try_fix_geometry(out_geom) if not valid: logger.warning("geometry invalid even with buffer, skipping") lost_features.append(out_feat.GetFID()) continue # Transform geometry out_geom.Transform(reproject) # flattening to 2d if flatten: out_geom.FlattenTo2D() # Set geometry and create feature out_feat.SetGeometry(out_geom) out_layer.CreateFeature(out_feat) logger.info("check - delete ogc_fid if exists") out_layer_defn = out_layer.GetLayerDefn() for n in range(out_layer_defn.GetFieldCount()): field = out_layer_defn.GetFieldDefn(n) if field.name == "ogc_fid": out_layer.DeleteField(n) break logger.info("check - Features count") out_feature_count = out_layer.GetFeatureCount() if len(lost_features) > 0: logger.warning("Lost {} features during corrections".format( len(lost_features))) logger.warning("FIDS: {}".format(lost_features)) elif in_feature_count > out_feature_count: logger.warning("In feature count greater than out feature count") mem_layer = None mem_datasource = None out_layer = None return out_datasource, layer_name
driver = ogr.GetDriverByName('ESRI Shapefile') #open the file using the required driver dataSource = driver.Open(filename, gdalconst.GA_ReadOnly) # get the layer layer = dataSource.GetLayer(0) #get basic info about the layer layerName = layer.GetName() layerTypeInt = layer.GetGeomType() layerExtent = layer.GetExtent() #convert integer layertype to text equivalent layerTypeStr = ogr.GeometryTypeToName(layerTypeInt) #print the name, type and extent of layer print 'Layer', layerName,'is a', layerTypeStr,'layer.' #step 4a above --- #get access to the layer's non-spatial info: number of fields, #field names, field types, etc. featureDefn = layer.GetLayerDefn() #get and print the number of fields fieldCount = featureDefn.GetFieldCount() print "The layer’s feature definition has the following", fieldCount, "fields:" #step 4b above --- print info about every field
def clip(in_layer, clip_geom): """ Clips in_layer geometries and clip_geom. - Multipart geometries are set as single part - Invalid geometries are first fixed, still not valid, then skip - Foreign geomtries (e.g., points) which are a result of a clip, are also skipped. - Parameters ---------- in_layer : ogr layer clip_geom : ogr geometry Returns ------- out_datasource : ogr datasource """ in_layer_geom_type = in_layer.GetGeomType() in_layer.ResetReading() in_layer.SetSpatialFilter(clip_geom) out_datasource = copymem(in_layer, geom_type=in_layer_geom_type) out_layer = out_datasource[0] print("starting clip") for out_feat in tqdm(in_layer): out_geom = out_feat.GetGeometryRef() try: if out_geom.Intersects(clip_geom.Boundary()): intersect = out_geom.Intersection(clip_geom) intersect_type = intersect.GetGeometryType() if not intersect.IsValid(): intersect, valid = fix_geometry(intersect) if not valid: print("skipping invalid intersect") continue if intersect_type > 3 or intersect_type < 0: # multiparts for geom_part in intersect: if not geom_part.IsValid(): geom_part, valid = fix_geometry(geom_part) if not valid: print("skipping invalid part") continue geom_part_type = geom_part.GetGeometryType() if geom_part_type != in_layer_geom_type: name = ogr.GeometryTypeToName(geom_part_type) print("Found foreign type:", name) continue out_feat.SetGeometry(geom_part) out_layer.CreateFeature(out_feat) else: out_feat.SetGeometry(intersect) out_layer.CreateFeature(out_feat) elif out_geom.Within(clip_geom): out_feat.SetGeometry(out_geom) out_layer.CreateFeature(out_feat) else: pass except Exception as e: print(e) out_layer = None return out_datasource
def difference(vector_layer, difference_layer): """ This function takes a difference between vector layer and difference layer. - Takes into account multiparts and single parts. - It also leaves geometries which are not valid. Parameters ---------- vector_layer : ogr layer - singleparts input vector. difference_layer : ogr layer difference layer. Returns ------- out_datasource : ogr datasource - multiparts """ vector_layer_geom_type = vector_layer.GetGeomType() if vector_layer_geom_type == 1: geometry_types = [1, 4] elif vector_layer_geom_type == 2: geometry_types = [2, 5] elif vector_layer_geom_type == 3: geometry_types = [3, 6] else: pass out_datasource = copymem(vector_layer, geom_type=vector_layer_geom_type) out_layer = out_datasource[0] vector_layer_defn = vector_layer.GetLayerDefn() print("starting to make a difference_layer") vector_layer.ResetReading() for vector_feat in tqdm(vector_layer): vector_geom = vector_feat.GetGeometryRef() vector_geom, valid = fix_geometry(vector_geom) if not valid: print("Input geometry not valid, skipping") continue difference_layer.ResetReading() difference_layer.SetSpatialFilter(vector_geom) for fid, difference_feat in enumerate(difference_layer): difference_geom = difference_feat.GetGeometryRef() difference_geom, valid = fix_geometry(difference_geom) if not valid: print("Difference layer geometry not valid, skipping") continue if difference_geom.Intersects(vector_geom): difference = vector_geom.Difference(difference_geom) diff_part_type = difference.GetGeometryType() if diff_part_type not in geometry_types: # Check if geometry collection if diff_part_type == ogr.wkbGeometryCollection: for geom_part in difference: if geom_part.GetGeometryType( ) == vector_layer_geom_type: vector_geom, valid = fix_geometry(geom_part) else: name = ogr.GeometryTypeToName(diff_part_type) print("Found foreign geometry:", name) continue else: vector_geom, valid = fix_geometry(difference) else: pass out_layer = append_feature(out_layer, vector_layer_defn, vector_geom, vector_feat.items()) out_layer = None return out_datasource
def correct(in_layer, layer_name="", epsg=3857): """ This function standardizes a vector layer: 1. Multipart to singleparts 2. 3D polygon to 2D polygon 3. Reprojection 4. Fix geometry for self intersections Parameters ---------- in_layer : ogr layer layer_name : string, optional The default is ''. epsg : int, optional The default is 3857. Raises ------ ValueError For a z-type geometry Returns ------- out_datasource : ogr datasource """ try: # retrieving lost features lost_features = [] in_feature_count = in_layer.GetFeatureCount() # Get inspatial reference and geometry from in shape geom_type = in_layer.GetGeomType() in_spatial_ref = in_layer.GetSpatialRef() in_layer.ResetReading() mem_datasource = create_mem_ds() mem_layer = mem_datasource.CreateLayer(layer_name, in_spatial_ref, geom_type) layer_defn = in_layer.GetLayerDefn() for i in range(layer_defn.GetFieldCount()): field_defn = layer_defn.GetFieldDefn(i) mem_layer.CreateField(field_defn) print("info", "check - Multipart to singlepart") lost_feat = multipoly2poly(in_layer, mem_layer) lost_features = lost_features + lost_feat if mem_layer.GetFeatureCount() == 0: print("error", "Multipart to singlepart failed") return 1 spatial_ref_3857 = osr.SpatialReference() spatial_ref_3857.ImportFromEPSG(int(epsg)) reproject = osr.CoordinateTransformation(in_spatial_ref, spatial_ref_3857) flatten = False geom_name = ogr.GeometryTypeToName(geom_type) if "3D" in geom_name: print("warning", "geom type: " + geom_name) print("info", "Flattening to 2D") flatten = True elif geom_type < 0: print("error", "geometry invalid, most likely has a z-type") raise ValueError( "geometry invalid, most likely has a z-type", "geom type: ", geom_name, ) # Create output dataset and force dataset to multiparts if geom_type == 6: geom_type = 3 # polygon elif geom_type == 5: geom_type = 2 # linestring elif geom_type == 4: geom_type = 1 # point out_datasource = create_mem_ds() out_layer = out_datasource.CreateLayer(layer_name, spatial_ref_3857, geom_type) layer_defn = in_layer.GetLayerDefn() # Copy fields from memory layer to output dataset for i in range(layer_defn.GetFieldCount()): out_layer.CreateField(layer_defn.GetFieldDefn(i)) print("info", "check - Reproject layer to {}".format(str(epsg))) for out_feat in tqdm(mem_layer): out_geom = out_feat.GetGeometryRef() try: out_geom, valid = fix_geometry(out_geom) except Exception as e: print(e) print(out_feat.GetFID()) if not valid: print("warning", "geometry invalid even with buffer, skipping") lost_features.append(out_feat.GetFID()) continue # Force and transform geometry out_geom = ogr.ForceTo(out_geom, geom_type) out_geom.Transform(reproject) # flattening to 2d if flatten: out_geom.FlattenTo2D() # Set geometry and create feature out_feat.SetGeometry(out_geom) out_layer.CreateFeature(out_feat) print("info", "check - delete ogc_fid if exists") out_layer_defn = out_layer.GetLayerDefn() for n in range(out_layer_defn.GetFieldCount()): field = out_layer_defn.GetFieldDefn(n) if field.name == "ogc_fid": out_layer.DeleteField(n) break print("info", "check - Features count") out_feature_count = out_layer.GetFeatureCount() if len(lost_features) > 0: print( "warning", "Lost {} features during corrections".format( len(lost_features)), ) print("warning", "FIDS: {}".format(lost_features)) elif in_feature_count > out_feature_count: print("warning", "In feature count greater than out feature count") else: pass except Exception as e: print(e) finally: mem_layer = None mem_datasource = None out_layer = None print("Finished vector corrections") return out_datasource, layer_name