Example #1
0
    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
Example #2
0
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
Example #3
0
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())
Example #5
0
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()
Example #6
0
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)
Example #10
0
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)
Example #11
0
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
Example #12
0
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))
Example #13
0
def ogr_get_layer_extent(lyr: ogr.Layer) -> GeoRectangle:
    r = GeoRectangle.from_min_max(*lyr.GetExtent())
    return r