def _axis_subset(self, crs_axis, nc_file):
        """
        Returns an axis subset using the given crs axis in the context of the nc file
        :param crs_axis:
        :param nc_file:
        :return:
        """
        user_axis = self._user_axis(self._get_user_axis_by_crs_axis_name(crs_axis.label), nc_file)

        high = user_axis.interval.high if user_axis.interval.high else user_axis.interval.low

        if not user_axis.irregular:
            geo_axis = RegularAxis(crs_axis.label, crs_axis.uom, user_axis.interval.low, high, user_axis.interval.low,
                                   crs_axis)
        else:
            geo_axis = IrregularAxis(crs_axis.label, crs_axis.uom, user_axis.interval.low, high, user_axis.interval.low,
                                     [0], crs_axis)

        if user_axis.type == UserAxisType.DATE:
            grid_low = 0
            grid_high = 0
        else:
            grid_low = 0
            number_of_geopixels = user_axis.interval.high - user_axis.interval.low
            grid_high = int(math.fabs(math.floor(grid_low + number_of_geopixels / user_axis.resolution)))
            if grid_high > grid_low:
                grid_high -= 1

        grid_axis = GridAxis(user_axis.order, crs_axis.label, user_axis.resolution, grid_low, grid_high)

        if crs_axis.is_easting():
            geo_axis.origin = geo_axis.low + user_axis.resolution / 2
        elif crs_axis.is_northing():
            geo_axis.origin = geo_axis.high + user_axis.resolution / 2
        elif crs_axis.is_future():
            geo_axis.origin = stringify(geo_axis.origin)
            geo_axis.low = stringify(geo_axis.low)
            if geo_axis.high is not None:
                geo_axis.high = stringify(geo_axis.high)
            user_axis.interval.low = stringify(user_axis.interval.low)
            if user_axis.interval.high is not None:
                user_axis.interval.high = stringify(user_axis.interval.high)
        return AxisSubset(CoverageAxis(geo_axis, grid_axis, user_axis.dataBound),
                          Interval(user_axis.interval.low, user_axis.interval.high))
Пример #2
0
    def _axis_subset(self, crs_axis, evaluator_slice, resolution=None):
        """
        Returns an axis subset using the given crs axis in the context of the gdal file
        :param CRSAxis crs_axis: the crs definition of the axis
        :param GDALEvaluatorSlice evaluator_slice: the evaluator for GDAL file
        :param resolution: Known axis resolution, no need to evaluate sentence expression from ingredient file (e.g: Sentinel2 recipe)
        :rtype AxisSubset
        """
        user_axis = self._user_axis(
            self._get_user_axis_by_crs_axis_name(crs_axis.label),
            evaluator_slice)
        if resolution is not None:
            user_axis.resolution = resolution

        high = user_axis.interval.high if user_axis.interval.high is not None else user_axis.interval.low

        if user_axis.type == UserAxisType.DATE:
            # it must translate datetime string to float by arrow for calculating later
            user_axis.interval.low = arrow.get(
                user_axis.interval.low).float_timestamp
            if user_axis.interval.high is not None:
                user_axis.interval.high = arrow.get(
                    user_axis.interval.high).float_timestamp

        if isinstance(user_axis, RegularUserAxis):
            geo_axis = RegularAxis(crs_axis.label, crs_axis.uom,
                                   user_axis.interval.low, high,
                                   user_axis.interval.low, crs_axis)
        else:
            # Irregular axis (coefficients must be number, not datetime string)
            if user_axis.type == UserAxisType.DATE:
                if crs_axis.is_time_day_axis():
                    coefficients = self._translate_day_date_direct_position_to_coefficients(
                        user_axis.interval.low, user_axis.directPositions)
                else:
                    coefficients = self._translate_seconds_date_direct_position_to_coefficients(
                        user_axis.interval.low, user_axis.directPositions)
            else:
                coefficients = self._translate_number_direct_position_to_coefficients(
                    user_axis.interval.low, user_axis.directPositions)

            self._update_for_slice_group_size(self.coverage_id, user_axis,
                                              crs_axis, coefficients)

            geo_axis = IrregularAxis(crs_axis.label, crs_axis.uom,
                                     user_axis.interval.low, high,
                                     user_axis.interval.low, coefficients,
                                     crs_axis)

        if not crs_axis.is_x_axis() and not crs_axis.is_y_axis():
            # GDAL model is 2D so on any axis except x/y we expect to have only one value
            grid_low = 0
            grid_high = None
            if user_axis.interval.high is not None:
                grid_high = 0
        else:
            grid_low = 0
            number_of_grid_points = decimal.Decimal(str(user_axis.interval.high)) \
                                  - decimal.Decimal(str(user_axis.interval.low))
            # number_of_grid_points = (geo_max - geo_min) / resolution
            grid_high = grid_low + number_of_grid_points / decimal.Decimal(
                user_axis.resolution)
            grid_high = HighPixelAjuster.adjust_high(grid_high)

            # Negative axis, e.g: Latitude (min <--- max)
            if user_axis.resolution < 0:
                grid_high = int(abs(math.floor(grid_high)))
            else:
                # Positive axis, e.g: Longitude (min --> max)
                grid_high = int(abs(math.ceil(grid_high)))

        # NOTE: Grid Coverage uses the direct intervals as in Rasdaman
        if self.grid_coverage is False and grid_high is not None:
            if grid_high > grid_low:
                grid_high -= 1

        grid_axis = GridAxis(user_axis.order, crs_axis.label,
                             user_axis.resolution, grid_low, grid_high)
        geo_axis.origin = PointPixelAdjuster.get_origin(user_axis, crs_axis)
        if user_axis.type == UserAxisType.DATE:
            self._translate_decimal_to_datetime(user_axis, geo_axis)
        # NOTE: current, gdal recipe supports only has 2 axes which are "bounded" (i.e: they exist as 2D axes in file)
        # and 1 or more another axes gotten (i.e: from fileName) which are not "bounded" to create 3D+ coverage.
        data_bound = crs_axis.is_y_axis() or crs_axis.is_x_axis()

        return AxisSubset(
            CoverageAxis(geo_axis, grid_axis, data_bound),
            Interval(user_axis.interval.low, user_axis.interval.high))
Пример #3
0
    def _axis_subset(self, crs_axis, gdal_file):
        """
        Returns an axis subset using the given crs axis in the context of the gdal file
        :param CRSAxis crs_axis: the crs definition of the axis
        :param File gdal_file: the gdal file
        :rtype AxisSubset
        """
        user_axis = self._user_axis(
            self._get_user_axis_by_crs_axis_name(crs_axis.label),
            GDALEvaluatorSlice(GDALGmlUtil(gdal_file.get_filepath())))
        high = user_axis.interval.high if user_axis.interval.high else user_axis.interval.low

        if isinstance(user_axis, RegularUserAxis):
            geo_axis = RegularAxis(crs_axis.label, crs_axis.uom,
                                   user_axis.interval.low, high,
                                   user_axis.interval.low, crs_axis)
        else:
            # if irregular axis value is fetched from fileName so the coefficient is [0] as slicing
            if user_axis.directPositions == AbstractToCoverageConverter.DIRECT_POSITIONS_SLICING:
                user_axis.directPositions = AbstractToCoverageConverter.COEFFICIENT_SLICING
            geo_axis = IrregularAxis(crs_axis.label, crs_axis.uom,
                                     user_axis.interval.low, high,
                                     user_axis.interval.low,
                                     user_axis.directPositions, crs_axis)

        if not crs_axis.is_easting() and not crs_axis.is_northing():
            # GDAL model is 2D so on any axis except x/y we expect to have only one value
            grid_low = 0
            grid_high = 0
        else:
            grid_low = 0
            number_of_grid_points = decimal.Decimal(str(user_axis.interval.high)) \
                                  - decimal.Decimal(str(user_axis.interval.low))
            # number_of_grid_points = (geo_max - geo_min) / resolution
            grid_high = grid_low + number_of_grid_points / decimal.Decimal(
                user_axis.resolution)
            grid_high = HighPixelAjuster.adjust_high(grid_high)

            # Negative axis, e.g: Latitude (min <--- max)
            if user_axis.resolution < 0:
                grid_high = int(abs(math.floor(grid_high)))
            else:
                # Positive axis, e.g: Longitude (min --> max)
                grid_high = int(abs(math.ceil(grid_high)))

        # NOTE: Grid Coverage uses the direct intervals as in Rasdaman
        if self.grid_coverage is False:
            if grid_high > grid_low:
                grid_high -= 1

        grid_axis = GridAxis(user_axis.order, crs_axis.label,
                             user_axis.resolution, grid_low, grid_high)
        geo_axis.origin = PointPixelAdjuster.get_origin(user_axis, crs_axis)
        if user_axis.type == UserAxisType.DATE:
            self._translate_decimal_to_datetime(user_axis, geo_axis)
        # NOTE: current, gdal recipe supports only has 2 axes which are "bounded" (i.e: they exist as 2D axes in file)
        # and 1 or more another axes gotten (i.e: from fileName) which are not "bounded" to create 3D+ coverage.
        data_bound = crs_axis.is_northing() or crs_axis.is_easting()

        return AxisSubset(
            CoverageAxis(geo_axis, grid_axis, data_bound),
            Interval(user_axis.interval.low, user_axis.interval.high))