Beispiel #1
0
    def get_grid_points(user_axis, crs_axis):
        """
        Computes the number of grid points corresponding to the axis.
        :param UserAxis user_axis: the axis as given by the user
        :param CrsAxis crs_axis: the corresponding crs axis
        :return: int gridPoints
        """
        # if no interval on the axis (slice), then 1 single grid point
        if user_axis.interval.high is None:
            return 1
        if isinstance(user_axis, RegularUserAxis):
            # number of geo-intervals over resolution
            if user_axis.type != UserAxisType.DATE:
                # number_of_grid_points = (geo_max - geo_min) / resolution
                grid_points = abs(
                    (decimal.Decimal(str(user_axis.interval.high)) -
                     decimal.Decimal(str(user_axis.interval.low))) /
                    decimal.Decimal(str(user_axis.resolution)))
                # The resolution in ingredient file can have big factor to the calculation, so must take care
                if abs(
                        decimal.Decimal(str(grid_points), ROUND_UP) -
                        grid_points) > HighPixelAjuster.THRESHOLD:
                    log.warning(
                        "The computed number of grid points is not an integer for axis "
                        + user_axis.name +
                        ". This usually indicates that the resolution is not correct."
                    )

                grid_points = HighPixelAjuster.adjust_high(grid_points)
                # Negative axis (e.g: latitude) min <--- max
                if user_axis.resolution < 0:
                    return int(math.floor(grid_points))
                else:
                    # Positive axis (e.g: longitude) min ---> max
                    return int(math.ceil(grid_points))
            else:
                time_difference = user_axis.interval.high - user_axis.interval.low
                # AS time always point to future (min --> max)
                if crs_axis.is_time_day_axis():
                    # days ((seconds / 86400) / resolution)
                    grid_points = abs(
                        (decimal.Decimal(str(time_difference)) /
                         decimal.Decimal(DateTimeUtil.DAY_IN_SECONDS)) /
                        decimal.Decimal(str(user_axis.resolution)))
                    grid_points = HighPixelAjuster.adjust_high(grid_points)

                    return int(math.ceil(grid_points))
                else:
                    # seconds (seconds / resolution)
                    grid_points = abs(
                        (decimal.Decimal(str(time_difference)) /
                         decimal.Decimal(str(user_axis.resolution))))
                    grid_points = HighPixelAjuster.adjust_high(grid_points)

                    return int(math.ceil(grid_points))
        else:
            # number of direct positions (i.e: irregular axis with coefficients [0, 1, 3, 5, 8, 15])
            return len(user_axis.directPositions)
Beispiel #2
0
    def get_origin(user_axis, crs_axis):
        """
        Computes the origin for the user_axis by shifting the limit with half resolution.
        :param UserAxis user_axis: the axis as given by the user.
        :return: float origin
        """
        # if axis is datetime then just return the low
        if user_axis.type == UserAxisType.DATE:
            return PointPixelAdjuster.get_origin_for_time_axis(
                user_axis, crs_axis)

        if isinstance(user_axis, RegularUserAxis):
            if user_axis.resolution > 0 or user_axis.interval.high is None:
                # axis goes from low to high, so origin is lowest, with half a pixel shift
                # min (min + 0.5*resolution) --> max
                return decimal.Decimal(str(user_axis.interval.low))\
                       + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution))
            else:
                # axis goes from high to low, so origin is highest, with half pixel shift (resolution is negative)
                # min <---- (max + 0.5*resolution) max
                return decimal.Decimal(str(user_axis.interval.high))\
                       + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution))
        else:
            # irregular axis, the same but without shift
            # normally, irregular axis points from min ---> max, so origin is min (e.g: time ansidate, unixtime)
            if user_axis.resolution > 0 or user_axis.interval.high is None:
                return user_axis.interval.low
            else:
                return user_axis.interval.high
Beispiel #3
0
    def adjust_axis_bounds_to_continuous_space(user_axis, crs_axis):
        """
        Moves pixels inside the user_axis from the middle of the interval to the bounds of the interval.
        :param UserAxis user_axis: the axis given by the user
        :param crs_axis is the axis from SECORE (e.g: 4326, Ansidate, UnixTime)
        :return: None
        """
        if user_axis.type == UserAxisType.DATE:
            PointPixelAdjuster.adjust_axis_bounds_for_time_axis(user_axis, crs_axis)
        else:
            # if low < high, adjust it
            if user_axis.interval.high is not None and user_axis.interval.low > user_axis.interval.high:
                user_axis.interval.low, user_axis.interval.high = user_axis.interval.high, user_axis.interval.low

            if isinstance(user_axis, RegularUserAxis):
                user_axis.interval.low = decimal.Decimal(str(user_axis.interval.low)) \
                                         - decimal.Decimal(str(0.5)) * abs(decimal.Decimal(str(user_axis.resolution)))
                if user_axis.interval.high:
                    user_axis.interval.high = decimal.Decimal(str(user_axis.interval.high)) \
                                              + decimal.Decimal(str(0.5)) * abs(decimal.Decimal(str(user_axis.resolution)))
Beispiel #4
0
    def adjust_axis_bounds_for_time_axis(user_axis, crs_axis):
        # convert to timestamp and change the axis type
        user_axis.interval.low = arrow.get(
            user_axis.interval.low).float_timestamp
        if user_axis.interval.high:
            user_axis.interval.high = arrow.get(
                user_axis.interval.high).float_timestamp

        # if low < high, adjust it
        if user_axis.interval.high is not None and user_axis.interval.low > user_axis.interval.high:
            user_axis.interval.low, user_axis.interval.high = user_axis.interval.high, user_axis.interval.low

        # The formula for all regular axes is when "pixelIsPoint":
        # min = min - 0.5 * resolution
        # max = max + 0.5 * resolution
        if isinstance(user_axis, RegularUserAxis):
            # if axis is time axis
            if crs_axis.is_time_day_axis():
                user_axis.interval.low = decimal.Decimal(str(user_axis.interval.low)) \
                                       - decimal.Decimal(0.5) * decimal.Decimal(str(abs(user_axis.resolution))) * DateTimeUtil.DAY_IN_SECONDS
                if user_axis.interval.high:
                    user_axis.interval.high = decimal.Decimal(str(user_axis.interval.high)) \
                                            + decimal.Decimal(0.5) * decimal.Decimal(str(abs(user_axis.resolution))) * DateTimeUtil.DAY_IN_SECONDS
            else:
                # if axis is normal axis (lat, lon, index1d,...)
                user_axis.interval.low = decimal.Decimal(str(user_axis.interval.low)) \
                                       - decimal.Decimal(0.5) * decimal.Decimal(str(abs(user_axis.resolution)))
                if user_axis.interval.high:
                    user_axis.interval.high = decimal.Decimal(str(user_axis.interval.high)) \
                                            + decimal.Decimal(0.5) * decimal.Decimal(str(abs(user_axis.resolution)))
Beispiel #5
0
    def get_origin_for_time_axis(user_axis, crs_axis):
        user_axis.interval.low = arrow.get(
            user_axis.interval.low).float_timestamp
        if user_axis.interval.high:
            user_axis.interval.high = arrow.get(
                user_axis.interval.high).float_timestamp

        if isinstance(user_axis, RegularUserAxis):
            # ansidate, need to calculate with day in seconds
            if crs_axis.is_time_day_axis:
                if user_axis.resolution > 0 or user_axis.interval.high is None:
                    # axis goes from low to high, so origin is lowest, with half a pixel shift
                    return decimal.Decimal(str(user_axis.interval.low))\
                         + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution)) * DateTimeUtil.DAY_IN_SECONDS
                else:
                    # axis goes from high to low, so origin is highest, with half pixel shift (resolution is negative)
                    return decimal.Decimal(str(user_axis.interval.high))\
                        + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution)) * DateTimeUtil.DAY_IN_SECONDS
            else:
                # unix time, already in seconds
                if user_axis.resolution > 0 or user_axis.interval.high is None:
                    # axis goes from low to high, so origin is lowest, with half a pixel shift
                    return decimal.Decimal(str(user_axis.interval.low))\
                         + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution))
                else:
                    # axis goes from high to low, so origin is highest, with half pixel shift (resolution is negative)
                    return decimal.Decimal(str(user_axis.interval.high))\
                         + decimal.Decimal(0.5) * decimal.Decimal(str(user_axis.resolution))
        else:
            # irregular axis, the same but without shift
            if user_axis.resolution > 0 or user_axis.interval.high is None:
                return user_axis.interval.low
            else:
                return user_axis.interval.high