Пример #1
0
 def get_converter_class(self):
     return get_converter(self.value)
Пример #2
0
 def get_converter_class(self):
     return get_converter(self.value)
Пример #3
0
    def _validate_(self):
        ocgis_lh(logger="operations", msg="validating operations")

        def _raise_(msg, obj=OutputFormat):
            e = DefinitionValidationError(obj, msg)
            ocgis_lh(exc=e, logger="operations")

        # assert the driver may be written to the appropriate output format
        for rd in self.dataset.iter_request_datasets():
            rd.driver.validate_ops(self)

        # validate the converter
        converter_klass = get_converter(self.output_format)
        converter_klass.validate_ops(self)

        # no regridding with a spatial operation of clip
        if self.regrid_destination is not None:
            if self.spatial_operation == "clip":
                msg = 'Regridding not allowed with spatial "clip" operation.'
                raise DefinitionValidationError(SpatialOperation, msg)

        # collect projections for the dataset sets. None is returned if one is not parsable. the WGS84 default is
        # actually done in the RequestDataset object.
        projections = []
        for rd in self.dataset.itervalues():
            if not any([_ == rd.crs for _ in projections]):
                projections.append(rd.crs)

        # if there is not output CRS and projections differ, raise an exception. however, it is okay to have data with
        # different projections in the numpy output.
        if len(projections) > 1 and self.output_format != "numpy":  # @UndefinedVariable
            if self.output_crs is None:
                _raise_(
                    "Dataset coordinate reference systems must be equivalent if no output CRS is chosen.", obj=OutputCRS
                )

        # clip and/or aggregation operations may not be written back to CFRotatedPole at this time. hence, the output
        # crs must be set to CFWGS84.
        if CFRotatedPole in map(type, projections):
            if self.output_crs is not None and not isinstance(self.output_crs, WGS84):
                msg = (
                    '{0} data may only be written to the same coordinate system (i.e. "output_crs=None") ' "or {1}."
                ).format(CFRotatedPole.__name__, CFWGS84.__name__)
                _raise_(msg, obj=OutputCRS)
            if self.aggregate or self.spatial_operation == "clip":
                msg = (
                    "{0} data if clipped or spatially averaged must be written to "
                    '{1}. The "output_crs" is being updated to {2}.'
                ).format(CFRotatedPole.__name__, CFWGS84.__name__, CFWGS84.__name__)
                ocgis_lh(level=logging.WARN, msg=msg, logger="operations")
                self._get_object_("output_crs")._value = CFWGS84()

        # only WGS84 may be written to to GeoJSON
        if self.output_format == "geojson":
            if any([element != WGS84() for element in projections if element is not None]):
                _raise_("Only data with a WGS84 projection may be written to GeoJSON.")
            if self.output_crs is not None:
                if self.output_crs != WGS84():
                    _raise_("Only data with a WGS84 projection may be written to GeoJSON.")

        # snippet only relevant for subsetting not operations with a calculation or time region
        if self.snippet:
            if self.calc is not None:
                _raise_(
                    "Snippets are not implemented for calculations. Apply a limiting time range for faster responses.",
                    obj=Snippet,
                )
            for rd in self.dataset.iter_request_datasets():
                if rd.time_region is not None:
                    _raise_("Snippets are not implemented for time regions.", obj=Snippet)

        # no slicing with a geometry - can easily lead to extent errors
        if self.slice is not None:
            assert self.geom is None

        # file only operations only valid for netCDF and calculations.
        if self.file_only:
            if self.output_format != "nc":
                _raise_('Only netCDF-CF may be written with file_only as "True".', obj=FileOnly)
            if self.calc is None:
                _raise_("File only outputs are only relevant for computations.", obj=FileOnly)

        # validate any calculations against the operations object. if the calculation is a string eval function do not
        # validate.
        if self.calc is not None:
            if self._get_object_("calc")._is_eval_function:
                if self.calc_grouping is not None:
                    msg = "Calculation groups are not applicable for string function expressions."
                    _raise_(msg, obj=CalcGrouping)
            else:
                for c in self.calc:
                    c["ref"].validate(self)