def get_geometry_type(self, layer: ogr.Layer) -> str: """Get geometry type human readable.""" try: logger.debug(ogr.GeometryTypeToName(layer.GetGeomType())) # if layer.GetGeomType(): # geom_type = layer.GetGeomType() # layer.ResetReading() # logger.error(geom_type) # return geom_type feat = layer.GetNextFeature() if not hasattr(feat, "GetGeometryRef"): logger.error("Unable to determine GeoMetryRef") return None layer_geom = feat.GetGeometryRef() if hasattr(layer_geom, "GetGeometryName"): return layer_geom.GetGeometryName() except Exception as err: logger.error( "Unable to retrieve geometry type for layer: {}. Trace: {}".format( layer.GetName(), err ) ) return None
def make_tracks(layer: ogr.Layer, coordinate_transformer) -> OrderedDict: tracks = OrderedDict() # this (ugly) style of feature iteration is a workaround for: # https://github.com/nextgis/pygdal/issues/31 feature = layer.GetNextFeature() while feature is not None: track_id = feature.GetField("track_id") track = tracks.setdefault(track_id, Track(track_id, coordinate_transformer)) segment_data = SegmentsData( segment_id=feature.GetField('segment_id'), vehicle_type=feature.GetField('vehicle_type'), timestamp=dt.datetime.strptime( feature.GetField("timestamp"), "%Y-%m-%d %H:%M:%S").replace(tzinfo=dt.timezone.utc)) geom = feature.GetGeometryRef() for lon, lat in geom.GetPoints(): geom = ogr.Geometry(ogr.wkbPoint) geom.AddPoint(lon, lat) segment_data.add_point(geom) track.add_segment(segment_data) feature = layer.GetNextFeature() for item in tracks.values(): item.prepare() return tracks
def reproject(layer: ogr.Layer, srs: osr.SpatialReference): '''Reprojects an existing layer given a spatial reference''' layer_name = layer.GetName() logging.info(f'reprojecting {layer_name}') projection = layer.GetSpatialRef() if projection is None: raise baseException( f'layer: {layer_name} does not have a spatial reference.', baseException.ERR_INPUT_LEVEL) # no action needed if projection.IsSame(srs): logging.info('no reprojection required') return try: # transform coordTrans = osr.CoordinateTransformation(projection, srs) # copy features layer.ResetReading() for ft in layer: geom = ft.GetGeometryRef() geom.Transform(coordTrans) ft.SetGeometry(geom) except Exception as e: raise baseException(f'layer: {layer_name} could not be reprojected.', baseException.ERR_CODE_LEVEL, e)
def __init__(self, ogr_data_source, ogr_layer: ogr.Layer): self.ogr_layer = ogr_layer self.ogr_data_source = ogr_data_source ogr_layer.thisown = 0 ogr_data_source.thisown = 0 self.fid_column_name = ogr_layer.GetFIDColumn() self.fields = list(self._get_fields())
def export(in_layer: Layer, out_layer: Layer, styler: Optional[Callable[[Feature], str]] = None) -> None: """Generate the output dataset from the input -- the difference being the style of the features""" for in_feature in in_layer: out_feature: Feature = ogr.Feature(out_layer.GetLayerDefn()) out_feature.SetFrom(in_feature) if styler is not None: style: str = styler(in_feature) out_feature.SetStyleString(style) out_layer.CreateFeature(out_feature) in_feature.Destroy() out_feature.Destroy()
def convert_dataset( path: Path, sndg_layer: ogr.Layer, ) -> None: file = ogr.Open(str(path)) layer = file.GetLayer() defn = sndg_layer.GetLayerDefn() for feature in layer: if not feature.GetFieldAsString('VALSOU'): # VALSOU is not set; feature has no sounding continue new = ogr.Feature(defn) new.SetField('RCID', feature.GetField('RCID')) new.SetField('DEPTH', feature.GetField('VALSOU')) new.SetGeometry(feature.GetGeometryRef().Centroid()) sndg_layer.CreateFeature(new)
def set_median_predom(const: dict, layer: ogr.Layer, region: str, *unused): '''Set the Median Predominance burn-in value''' try: burn_field = const['burn_field'] burn = ogr.FieldDefn(burn_field, ogr.OFTInteger) layer.CreateField(burn) # set burn-in values for each feature logging.info('setting median predominance') layer.ResetReading() for ft in layer: predominant = get_predom(const, ft) ft.SetField(burn_field, predominant) layer.SetFeature(ft) except Exception as e: raise baseException( f'could not set values in {layer.GetName()} for median predominance', baseException.ERR_CODE_LEVEL, e)
def get_features_from_layer(source_layer: ogr.Layer, destination_layer: ogr.Layer, title_provider: Callable[[ogr.Feature], str], x_min: float, y_min: float, x_max: float, y_max: float) -> None: memory_driver = ogr.GetDriverByName("Memory") clip_datasource = memory_driver.CreateDataSource("") clip_layer = clip_datasource.CreateLayer("clip_layer", geom_type=ogr.wkbPolygon) clip_geom = ogr.CreateGeometryFromWkt( f"POLYGON (({x_min} {y_min}, {x_max} {y_min}, {x_max} {y_max}, {x_min} {y_max}, {x_min} {y_min}))" ) clip_srs = osr.SpatialReference() clip_srs.SetFromUserInput(bbox_crs) clip_geom.AssignSpatialReference(clip_srs) feature_defn = clip_layer.GetLayerDefn() feature = ogr.Feature(feature_defn) feature.SetGeometry(clip_geom) clip_layer.CreateFeature(feature) result_datasource = memory_driver.CreateDataSource("") result_layer = result_datasource.CreateLayer( "result_layer", geom_type=ogr.wkbMultiLineString) ogr.Layer.Clip(source_layer, clip_layer, result_layer) id_field = ogr.FieldDefn(id_field_name, ogr.OFTInteger64) title_field = ogr.FieldDefn(title_field_name, ogr.OFTString) title_field.SetWidth(title_field_width) destination_layer.CreateField(id_field) destination_layer.CreateField(title_field) feature = result_layer.GetNextFeature() while feature is not None: geometry_ref = feature.GetGeometryRef() new_geometry = geometry_ref.Clone() new_feature = ogr.Feature(destination_layer.GetLayerDefn()) new_feature.SetGeometryDirectly(new_geometry) new_feature.SetField(id_field_name, feature.GetFID()) new_feature.SetField(title_field_name, title_provider(feature)[0:title_field_width]) destination_layer.CreateFeature(new_feature) feature = result_layer.GetNextFeature()
def set_median_ct(const: dict, layer: ogr.Layer, region: str, ice_type: str, *unused): '''Set the Median Concentration burn-in value''' try: water, land, nodata = const['water'], const['land'], const['nodata'] burn_field = const['burn_field'] burn = ogr.FieldDefn(burn_field, ogr.OFTInteger) layer.CreateField(burn) # set burn-in values for each feature logging.info('setting median ct') layer.ResetReading() for ft in layer: fa = ft.GetField('FA') fb = ft.GetField('FB') fc = ft.GetField('FC') concn = ft.GetField(ice_type) if concn is None or concn == '': concn = water elif '08' in [fa, fb, fc] and concn in ['9.7', '10.0']: concn = '11.0' elif '07' in [fa, fb, fc] and concn == '10.0': concn = '10.0' ft.SetField(burn_field, int(float(concn))) pnt_type = ft.GetField('PNT_TYPE') if pnt_type in ['101', '115', '107']: ft.SetField(burn_field, water) elif pnt_type in ['400', '900']: ft.SetField(burn_field, land) elif pnt_type in ['123', '128', '133', '143']: ft.SetField(burn_field, nodata) layer.SetFeature(ft) except Exception as e: raise baseException( f'could not set values in {layer.GetName()} for median concentration', baseException.ERR_CODE_LEVEL, e)
def set_frequency(const: dict, layer: ogr.Layer, region: str, ice_type: str, threshold: int = 1): '''Set the Frequency burn-in value''' try: water, nodata = const['water'], const['nodata'] burn_field = const['burn_field'] burn = ogr.FieldDefn(burn_field, ogr.OFTInteger) layer.CreateField(burn) # set burn-in values for each feature logging.info(f'setting frequency using threshold: {threshold}') layer.ResetReading() for ft in layer: pnt_type = ft.GetField('PNT_TYPE') concn = ft.GetField(ice_type) concn = 0.0 if not concn else float(concn) if pnt_type in ['101', '107', '115', '400', '900']: ft.SetField(burn_field, water) elif pnt_type in ['123', '128', '133', '143']: ft.SetField(burn_field, nodata) elif pnt_type in ['106', '117', '118', '120', '122', '144' ] and concn >= float(threshold): ft.SetField(burn_field, 1) elif pnt_type in ['106', '117', '118', '120', '122', '144' ] and concn < float(threshold): ft.SetField(burn_field, water) else: ft.SetField(burn_field, nodata) layer.SetFeature(ft) except Exception as e: raise baseException( f'could not set values in {layer.GetName()} for frequency', baseException.ERR_CODE_LEVEL, e)
def does_layer_has_att(layer: ogr.Layer, att_name: str): """ :param layer: layer to look for attributes in :param att_name: the name of the attribute to find :return: """ feature_defn = layer.GetLayerDefn() """ :type feature_defn: ogr.FeatureDefn """ for field_index in range(feature_defn.GetFieldCount()): field_defn = feature_defn.GetFieldDefn() """ :type field_defn: ogr.FieldDefn """ if field_defn.GetName() == att_name: return True return False
def create_fields(out_layer: Layer, in_def: FeatureDefn) -> None: """Generate the output dataset fields, using all the input fields""" for i in range(0, in_def.GetFieldCount()): out_layer.CreateField(in_def.GetFieldDefn(i))
def ogr_get_layer_extent(lyr: ogr.Layer) -> GeoRectangle: r = GeoRectangle.from_min_max(*lyr.GetExtent()) return r