コード例 #1
0
ファイル: config.py プロジェクト: puqiu/mapchete
 def output(self):
     """Output object of driver."""
     output_params = self._raw["output"]
     if "path" in output_params:
         output_params.update(
             path=os.path.normpath(
                 os.path.join(self.config_dir, output_params["path"])))
     output_params.update(
         type=self.output_pyramid.grid,
         pixelbuffer=self.output_pyramid.pixelbuffer,
         metatiling=self.output_pyramid.metatiling)
     if "format" not in output_params:
         raise MapcheteConfigError("output format not specified")
     if output_params["format"] not in available_output_formats():
         raise MapcheteConfigError(
             "format %s not available in %s" % (
                 output_params["format"], str(available_output_formats())))
     writer = load_output_writer(output_params)
     try:
         writer.is_valid_with_config(output_params)
     except Exception as e:
         logger.exception(e)
         raise MapcheteConfigError(
             "driver %s not compatible with configuration: %s" % (
                 writer.METADATA["driver_name"], e))
     return writer
コード例 #2
0
ファイル: config.py プロジェクト: puqiu/mapchete
def _validate_zooms(zooms):
    """
    Return a list of zoom levels.

    Following inputs are converted:
    - int --> [int]
    - dict{min, max} --> range(min, max + 1)
    - [int] --> [int]
    - [int, int] --> range(smaller int, bigger int + 1)
    """
    if isinstance(zooms, dict):
        if any([a not in zooms for a in ["min", "max"]]):
            raise MapcheteConfigError("min and max zoom required")
        zmin = _validate_zoom(zooms["min"])
        zmax = _validate_zoom(zooms["max"])
        if zmin > zmax:
            raise MapcheteConfigError(
                "max zoom must not be smaller than min zoom")
        return range(zmin, zmax + 1)
    elif isinstance(zooms, list):
        if len(zooms) == 1:
            return zooms
        elif len(zooms) == 2:
            zmin, zmax = sorted([_validate_zoom(z) for z in zooms])
            return range(zmin, zmax + 1)
        else:
            raise MapcheteConfigError(
                "when providing zooms as list, just min and max are allowed")
    else:
        return [_validate_zoom(zooms)]
コード例 #3
0
ファイル: __init__.py プロジェクト: gijs/mapchete
 def zoom_levels(self):
     """Determine valid process zoom levels."""
     # Read from raw configuration.
     if "process_zoom" in self.raw:
         zoom = [self.raw["process_zoom"]]
     elif all(k in self.raw
              for k in ("process_minzoom", "process_maxzoom")):
         zoom = [self.raw["process_minzoom"], self.raw["process_maxzoom"]]
     else:
         zoom = []
     # overwrite zoom if provided in additional_parameters
     zoom = self._delimiters["zoom"] if self._delimiters["zoom"] else zoom
     # # if zoom still empty, throw exception
     if not zoom:
         raise MapcheteConfigError("No zoom level(s) provided.")
     zoom = [zoom] if isinstance(zoom, int) else zoom
     if len(zoom) == 1:
         if zoom[0] < 0:
             raise MapcheteConfigError("Zoom level must be greater 0.")
         return zoom
     elif len(zoom) == 2:
         for i in zoom:
             if i < 0:
                 raise MapcheteConfigError("Zoom levels must be greater 0.")
         if zoom[0] < zoom[1]:
             return range(zoom[0], zoom[1] + 1)
         else:
             return range(zoom[1], zoom[0] + 1)
     else:
         raise MapcheteConfigError(
             "Zoom level parameter requires one or two value(s).")
コード例 #4
0
ファイル: config.py プロジェクト: puqiu/mapchete
    def baselevels(self):
        """
        Optional baselevels configuration.

        baselevels:
            min: <zoom>
            max: <zoom>
            lower: <resampling method>
            higher: <resampling method>
        """
        if "baselevels" not in self._raw:
            return {}
        baselevels = self._raw["baselevels"]
        minmax = {
            k: v for k, v in six.iteritems(baselevels) if k in ["min", "max"]}
        if not minmax:
            raise MapcheteConfigError(
                "no min and max values given for baselevels")
        for v in minmax.values():
            if not isinstance(v, int) or v < 0:
                raise MapcheteConfigError(
                    "invalid baselevel zoom parameter given: %s" % (
                        minmax.values()))
        return dict(
            zooms=range(
                minmax.get("min", min(self.zoom_levels)),
                minmax.get("max", max(self.zoom_levels)) + 1),
            lower=baselevels.get("lower", "nearest"),
            higher=baselevels.get("higher", "nearest"),
            tile_pyramid=BufferedTilePyramid(
                self.output_pyramid.grid,
                pixelbuffer=self.output_pyramid.pixelbuffer,
                metatiling=self.process_pyramid.metatiling))
コード例 #5
0
def write_output_metadata(output_params):
    """Dump output JSON and verify parameters if output metadata exist."""
    if "path" in output_params:
        metadata_path = os.path.join(output_params["path"], "metadata.json")
        logger.debug("check for output %s", metadata_path)
        try:
            existing_params = read_output_metadata(metadata_path)
            logger.debug("%s exists", metadata_path)
            logger.debug("existing output parameters: %s",
                         pformat(existing_params))
            existing_tp = existing_params["pyramid"]
            current_params = params_to_dump(output_params)
            logger.debug("current output parameters: %s",
                         pformat(current_params))
            current_tp = BufferedTilePyramid(**current_params["pyramid"])
            if existing_tp != current_tp:  # pragma: no cover
                raise MapcheteConfigError(
                    "pyramid definitions between existing and new output do not match: "
                    "%s != %s" % (existing_tp, current_tp))
            existing_format = existing_params["driver"]["format"]
            current_format = current_params["driver"]["format"]
            if existing_format != current_format:  # pragma: no cover
                raise MapcheteConfigError(
                    "existing output format does not match new output format: "
                    "%s != %s" % ((existing_format, current_format)))
        except FileNotFoundError:
            logger.debug("%s does not exist", metadata_path)
            dump_params = params_to_dump(output_params)
            # dump output metadata
            write_json(metadata_path, dump_params)
コード例 #6
0
ファイル: __init__.py プロジェクト: gijs/mapchete
 def output(self):
     """Output object of driver."""
     output_params = self.raw["output"]
     if "format" not in output_params:
         raise MapcheteConfigError("output format not specified")
     if output_params["format"] not in available_output_formats():
         raise MapcheteConfigError(
             "format %s not available in %s" %
             (output_params["format"], str(available_output_formats())))
     writer = load_output_writer(output_params)
     if not writer.is_valid_with_config(output_params):
         raise MapcheteConfigError(
             "driver %s not compatible with configuration: %s" %
             (writer.METADATA["driver_name"], output_params))
     return writer
コード例 #7
0
ファイル: config.py プロジェクト: elfmon/mapchete
def _load_process_module(process_path=None,
                         config_dir=None,
                         run_compile=False):
    if process_path.endswith(".py"):
        module_path = os.path.join(config_dir, process_path)
        if not os.path.isfile(module_path):
            raise MapcheteConfigError(f"{module_path} is not available")
        try:
            if run_compile:
                py_compile.compile(module_path, doraise=True)
            module_name = os.path.splitext(os.path.basename(module_path))[0]
            # load module
            spec = importlib.util.spec_from_file_location(
                module_name, module_path)
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)
            # required to make imported module available using multiprocessing
            sys.modules[module_name] = module
            # configure process file logger
            add_module_logger(module.__name__)
        except py_compile.PyCompileError as e:
            raise MapcheteProcessSyntaxError(e)
        except ImportError as e:
            raise MapcheteProcessImportError(e)
    else:
        try:
            module = importlib.import_module(process_path)
        except ImportError as e:
            raise MapcheteProcessImportError(e)
    return module
コード例 #8
0
ファイル: config.py プロジェクト: puqiu/mapchete
def _config_to_dict(input_config):
    if isinstance(input_config, dict):
        if "config_dir" not in input_config:
            raise MapcheteConfigError("config_dir parameter missing")
        return dict(input_config, mapchete_file=None)
    # from Mapchete file
    elif os.path.splitext(input_config)[1] == ".mapchete":
        with open(input_config, "r") as config_file:
            return dict(
                yaml.safe_load(config_file.read()),
                config_dir=os.path.dirname(os.path.realpath(input_config)),
                mapchete_file=input_config)
    # throw error if unknown object
    else:
        raise MapcheteConfigError(
            "Configuration has to be a dictionary or a .mapchete file.")
コード例 #9
0
ファイル: __init__.py プロジェクト: gijs/mapchete
def _strip_zoom(input_string, strip_string):
    """Return zoom level as integer or throws error."""
    try:
        element_zoom = input_string.strip(strip_string)
        return int(element_zoom)
    except Exception:
        raise MapcheteConfigError("zoom level could not be determined")
コード例 #10
0
ファイル: __init__.py プロジェクト: gijs/mapchete
 def process_file(self):
     """Absolute path of process file."""
     abs_path = os.path.join(self.config_dir, self.raw["process_file"])
     if os.path.isfile(abs_path):
         return abs_path
     else:
         raise MapcheteConfigError("%s is not available" % abs_path)
コード例 #11
0
ファイル: gtiff.py プロジェクト: robert-werner/mapchete
 def prepare(self, process_area=None, **kwargs):
     bounds = snap_bounds(
         bounds=Bounds(*process_area.intersection(
             box(*self.output_params["delimiters"]
                 ["effective_bounds"])).bounds),
         pyramid=self.pyramid,
         zoom=self.zoom) if process_area else self.output_params[
             "delimiters"]["effective_bounds"]
     height = math.ceil((bounds.top - bounds.bottom) /
                        self.pyramid.pixel_x_size(self.zoom))
     width = math.ceil((bounds.right - bounds.left) /
                       self.pyramid.pixel_x_size(self.zoom))
     logger.debug("output raster bounds: %s", bounds)
     logger.debug("output raster shape: %s, %s", height, width)
     self._profile = dict(
         GTIFF_DEFAULT_PROFILE,
         driver="GTiff",
         transform=Affine(self.pyramid.pixel_x_size(self.zoom), 0,
                          bounds.left, 0,
                          -self.pyramid.pixel_y_size(self.zoom),
                          bounds.top),
         height=height,
         width=width,
         count=self.output_params["bands"],
         crs=self.pyramid.crs,
         **{
             k: self.output_params.get(k, GTIFF_DEFAULT_PROFILE[k])
             for k in GTIFF_DEFAULT_PROFILE.keys()
         },
         bigtiff=self.output_params.get("bigtiff", "NO"))
     logger.debug("single GTiff profile: %s", self._profile)
     self.in_memory = (self.in_memory if self.in_memory is False else
                       height * width < IN_MEMORY_THRESHOLD)
     # set up rasterio
     if path_exists(self.path):
         if self.output_params["mode"] != "overwrite":
             raise MapcheteConfigError(
                 "single GTiff file already exists, use overwrite mode to replace"
             )
         else:
             logger.debug("remove existing file: %s", self.path)
             os.remove(self.path)
     # create output directory if necessary
     makedirs(os.path.dirname(self.path))
     logger.debug("open output file: %s", self.path)
     self._ctx = ExitStack()
     # (1) use memfile if output is remote or COG
     if self.cog or path_is_remote(self.path):
         if self.in_memory:
             self._memfile = self._ctx.enter_context(MemoryFile())
             self.dst = self._ctx.enter_context(
                 self._memfile.open(**self._profile))
         else:
             # in case output raster is too big, use tempfile on disk
             self._tempfile = self._ctx.enter_context(NamedTemporaryFile())
             self.dst = self._ctx.enter_context(
                 rasterio.open(self._tempfile.name, "w+", **self._profile))
     else:
         self.dst = self._ctx.enter_context(
             rasterio.open(self.path, "w+", **self._profile))
コード例 #12
0
ファイル: __init__.py プロジェクト: gijs/mapchete
 def __init__(self,
              input_config,
              zoom=None,
              bounds=None,
              single_input_file=None,
              mode="continue",
              debug=False):
     """Initialize configuration."""
     LOGGER.info("preparing configuration ...")
     if debug:
         LOGGER.setLevel(logging.DEBUG)
     if mode not in ["memory", "readonly", "continue", "overwrite"]:
         raise MapcheteConfigError("invalid process mode")
     LOGGER.debug("zooms provided to config: %s" % zoom)
     self.mode = mode
     # parse configuration
     LOGGER.debug("parse configuration ...")
     self._input_cache = {}
     self._process_area_cache = {}
     self.raw, self.mapchete_file, self.config_dir = self._parse_config(
         input_config, single_input_file=single_input_file)
     if not self.process_file:
         raise MapcheteConfigError("no process_file given")
     # set process delimiters
     self._delimiters = dict(zoom=zoom, bounds=bounds)
     # helper caches
     self._at_zoom_cache = {}
     self._global_process_area = None
     # other properties
     try:
         self.output_type = self.raw["output"]["type"]
     except KeyError:
         raise MapcheteConfigError("no output type given")
     if self.raw["output"]["type"] not in TILING_TYPES:
         raise MapcheteConfigError("output type is missing: %s" %
                                   PYRAMID_PARAMS.keys())
     self.process_pyramid = BufferedTilePyramid(
         self.output_type,
         metatiling=self.metatiling,
         pixelbuffer=self.pixelbuffer)
     self.output_pyramid = BufferedTilePyramid(
         self.output_type,
         metatiling=self.raw["output"]["metatiling"],
         pixelbuffer=self.raw["output"]["pixelbuffer"])
     self.crs = self.process_pyramid.crs
     LOGGER.debug("validate ...")
     self._validate()
コード例 #13
0
ファイル: config.py プロジェクト: puqiu/mapchete
def _validate_bounds(bounds):
    if any([
        not isinstance(bounds, (list, tuple)),
        len(bounds) != 4,
        any([not isinstance(i, (int, float)) for i in bounds])
    ]):
        raise MapcheteConfigError("bounds not valid")
    return bounds
コード例 #14
0
ファイル: __init__.py プロジェクト: ichem/mapchete
def _validate_process_file(config):
    abs_path = os.path.join(config["config_dir"], config["process_file"])
    if not os.path.isfile(abs_path):
        raise MapcheteConfigError("%s is not available" % abs_path)
    try:
        py_compile.compile(abs_path, doraise=True)
    except py_compile.PyCompileError as e:
        raise MapcheteProcessSyntaxError(e)
    return abs_path
コード例 #15
0
ファイル: config.py プロジェクト: elfmon/mapchete
 def process_func(self):
     """Import process function and make syntax check."""
     if self.mode == "readonly":
         raise MapcheteConfigError(
             "process function cannot be loaded in readonly mode.")
     else:
         return get_process_func(process_path=self.process_path,
                                 config_dir=self.config_dir,
                                 run_compile=True)
コード例 #16
0
 def bounds(self):
     """Process bounds as defined in the configuration."""
     if self._raw["bounds"] is None:
         return self.process_pyramid.bounds
     else:
         try:
             return validate_bounds(self._raw["bounds"])
         except Exception as e:
             raise MapcheteConfigError(e)
コード例 #17
0
ファイル: config.py プロジェクト: elfmon/mapchete
    def _get_process_area(self,
                          area=None,
                          bounds=None,
                          area_fallback=None,
                          bounds_fallback=None,
                          area_crs=None,
                          bounds_crs=None):
        """
        Determine process area by combining configuration with instantiation arguments.

        In the configuration the process area can be provided by using the (1) ``area``
        option, (2) ``bounds`` option or (3) a combination of both.

        (1) If only ``area`` is provided, output shall be the area geometry
        (2) If only ``bounds`` is provided, output shall be box(*self.bounds)
        (3) If both are provided, output shall be the intersection between ``area`` and
        ``bounds``

        The area parameter can be provided in multiple variations, see _guess_geometry().
        """
        try:
            dst_crs = self.process_pyramid.crs

            if bounds is None and area is None:
                return area_fallback

            elif bounds is None:
                area, crs = _guess_geometry(area, base_dir=self.config_dir)
                # in case vector file has no CRS use manually provided CRS
                area_crs = crs or area_crs

                return reproject_geometry(area,
                                          src_crs=area_crs or dst_crs,
                                          dst_crs=dst_crs)

            elif area is None:
                return reproject_geometry(box(*validate_bounds(bounds)),
                                          src_crs=bounds_crs or dst_crs,
                                          dst_crs=dst_crs)

            else:
                area, crs = _guess_geometry(area, base_dir=self.config_dir)
                # in case vector file has no CRS use manually provided CRS
                area_crs = crs or area_crs

                bounds = validate_bounds(bounds)

                # reproject area and bounds to process CRS and return intersection
                return reproject_geometry(
                    area, src_crs=area_crs or dst_crs,
                    dst_crs=dst_crs).intersection(
                        reproject_geometry(box(*validate_bounds(bounds)),
                                           src_crs=bounds_crs or dst_crs,
                                           dst_crs=dst_crs), )
        except Exception as e:
            raise MapcheteConfigError(e)
コード例 #18
0
 def output(self):
     """Output writer class of driver."""
     writer = load_output_writer(self._output_params)
     try:
         writer.is_valid_with_config(self._output_params)
     except Exception as e:
         logger.exception(e)
         raise MapcheteConfigError(
             "driver %s not compatible with configuration: %s" %
             (writer.METADATA["driver_name"], e))
     return writer
コード例 #19
0
ファイル: config.py プロジェクト: puqiu/mapchete
def get_zoom_levels(process_zoom_levels=None, init_zoom_levels=None):
    """Validate and return zoom levels."""
    process_zoom_levels = _validate_zooms(process_zoom_levels)
    if init_zoom_levels is None:
        return process_zoom_levels
    else:
        init_zoom_levels = _validate_zooms(init_zoom_levels)
        if not set(init_zoom_levels).issubset(set(process_zoom_levels)):
            raise MapcheteConfigError(
                "init zooms must be a subset of process zoom")
        return init_zoom_levels
コード例 #20
0
    def _output_params(self):
        """Output params of driver."""
        output_params = dict(self._raw["output"],
                             grid=self.output_pyramid.grid,
                             pixelbuffer=self.output_pyramid.pixelbuffer,
                             metatiling=self.output_pyramid.metatiling,
                             delimiters=self._delimiters,
                             mode=self.mode)
        if "path" in output_params:
            output_params.update(path=absolute_path(path=output_params["path"],
                                                    base_dir=self.config_dir))

        if "format" not in output_params:
            raise MapcheteConfigError("output format not specified")

        if output_params["format"] not in available_output_formats():
            raise MapcheteConfigError(
                "format %s not available in %s" %
                (output_params["format"], str(available_output_formats())))
        return output_params
コード例 #21
0
ファイル: config.py プロジェクト: yanafedorchuk/mapchete
def _map_to_new_config(config):
    if "pyramid" not in config:
        warnings.warn("'pyramid' needs to be defined in root config element.")
        config["pyramid"] = dict(grid=config["output"]["type"],
                                 metatiling=config.get("metatiling", 1),
                                 pixelbuffer=config.get("pixelbuffer", 0))
    if "zoom_levels" not in config:
        warnings.warn(
            "use new config element 'zoom_levels' instead of 'process_zoom', "
            "'process_minzoom' and 'process_maxzoom'")
        if "process_zoom" in config:
            config["zoom_levels"] = config["process_zoom"]
        elif all([i in config
                  for i in ["process_minzoom", "process_maxzoom"]]):
            config["zoom_levels"] = dict(min=config["process_minzoom"],
                                         max=config["process_maxzoom"])
        else:
            raise MapcheteConfigError(
                "process zoom levels not provided in config")
    if "bounds" not in config:
        if "process_bounds" in config:
            warnings.warn(
                "'process_bounds' are deprecated and renamed to 'bounds'")
            config["bounds"] = config["process_bounds"]
        else:
            config["bounds"] = None
    if "input" not in config:
        if "input_files" in config:
            warnings.warn(
                "'input_files' are deprecated and renamed to 'input'")
            config["input"] = config["input_files"]
        else:
            raise MapcheteConfigError("no 'input' found")
    elif "input_files" in config:
        raise MapcheteConfigError(
            "'input' and 'input_files' are not allowed at the same time")
    if "process_file" in config:
        warnings.warn("'process_file' is deprecated and renamed to 'process'")
        config["process"] = config.pop("process_file")

    return config
コード例 #22
0
ファイル: execute.py プロジェクト: ichem/mapchete
def main(args=None):
    """Execute a Mapchete process."""
    parsed = args

    multi = parsed.multi if parsed.multi else cpu_count()
    mode = "overwrite" if parsed.overwrite else "continue"
    # process single tile
    if parsed.tile:
        conf = yaml.load(open(parsed.mapchete_file, "r").read())
        if "output" not in conf:
            raise MapcheteConfigError("output definition missing")
        if "pyramid" not in conf or "grid" not in conf["pyramid"]:
            raise MapcheteConfigError("pyramid definition missing")
        tile = BufferedTilePyramid(
            conf["pyramid"]["grid"],
            metatiling=conf["pyramid"].get("metatiling", 1),
            pixelbuffer=conf["pyramid"].get("pixelbuffer",
                                            0)).tile(*parsed.tile)
        with mapchete.open(parsed.mapchete_file,
                           mode=mode,
                           bounds=tile.bounds,
                           zoom=tile.zoom,
                           single_input_file=parsed.input_file,
                           debug=parsed.debug) as mp:
            mp.batch_process(tile=parsed.tile,
                             quiet=parsed.quiet,
                             debug=parsed.debug,
                             logfile=parsed.logfile)
    # initialize and run process
    else:
        with mapchete.open(parsed.mapchete_file,
                           bounds=parsed.bounds,
                           zoom=parsed.zoom,
                           mode=mode,
                           single_input_file=parsed.input_file,
                           debug=parsed.debug) as mp:
            mp.batch_process(multi=multi,
                             quiet=parsed.quiet,
                             debug=parsed.debug,
                             zoom=parsed.zoom,
                             logfile=parsed.logfile)
コード例 #23
0
ファイル: config.py プロジェクト: puqiu/mapchete
def _validate_process_file(config):
    abs_path = os.path.join(config["config_dir"], config["process_file"])
    if not os.path.isfile(abs_path):
        raise MapcheteConfigError("%s is not available" % abs_path)
    try:
        py_compile.compile(abs_path, doraise=True)
        imp.load_source(os.path.splitext(os.path.basename(abs_path))[0], abs_path)
    except py_compile.PyCompileError as e:
        raise MapcheteProcessSyntaxError(e)
    except ImportError as e:
        raise MapcheteProcessImportError(e)
    return abs_path
コード例 #24
0
ファイル: __init__.py プロジェクト: gijs/mapchete
    def baselevels(self):
        """
        Optional baselevels configuration.

        baselevels:
            min: <zoom>
            max: <zoom>
            lower: <resampling method>
            higher: <resampling method>
        """
        try:
            baselevels = self.raw["baselevels"]
        except KeyError:
            return {}
        minmax = {
            k: v
            for k, v in baselevels.iteritems() if k in ["min", "max"]
        }
        if not minmax:
            raise MapcheteConfigError(
                "no min and max values given for baselevels")
        for v in minmax.values():
            if v < 0 or not isinstance(v, int):
                raise MapcheteConfigError(
                    "invalid baselevel zoom parameter given: %s" %
                    (minmax.values()))
        base_min = minmax["min"] if "min" in minmax else min(self.zoom_levels)
        base_max = minmax["max"] if "max" in minmax else max(self.zoom_levels)
        resampling_lower = (baselevels["lower"]
                            if "lower" in baselevels else "nearest")
        resampling_higher = (baselevels["higher"]
                             if "higher" in baselevels else "nearest")
        return dict(zooms=range(base_min, base_max + 1),
                    lower=resampling_lower,
                    higher=resampling_higher,
                    tile_pyramid=BufferedTilePyramid(
                        self.output_pyramid.type,
                        pixelbuffer=self.output_pyramid.pixelbuffer,
                        metatiling=self.process_pyramid.metatiling))
コード例 #25
0
    def init_zoom_levels(self):
        """
        Zoom levels this process is currently initialized with.

        This gets triggered by using the ``zoom`` kwarg. If not set, it will
        be equal to self.zoom_levels.
        """
        try:
            return get_zoom_levels(
                process_zoom_levels=self._raw["zoom_levels"],
                init_zoom_levels=self._raw["init_zoom_levels"])
        except Exception as e:
            raise MapcheteConfigError(e)
コード例 #26
0
    def init_bounds(self):
        """
        Process bounds this process is currently initialized with.

        This gets triggered by using the ``init_bounds`` kwarg. If not set, it will
        be equal to self.bounds.
        """
        if self._raw["init_bounds"] is None:
            return self.bounds
        else:
            try:
                return validate_bounds(self._raw["init_bounds"])
            except Exception as e:
                raise MapcheteConfigError(e)
コード例 #27
0
ファイル: __init__.py プロジェクト: ichem/mapchete
    def init_zoom_levels(self):
        """
        Zoom levels this process is currently initialized with.

        This gets triggered by using the ``zoom`` kwarg. If not set, it will
        be equal to self.zoom_levels.
        """
        if self._raw["init_zoom_levels"] is None:
            return self.zoom_levels
        else:
            init_zooms = _validate_zooms(self._raw["init_zoom_levels"])
            if not set(init_zooms).issubset(set(self.zoom_levels)):
                raise MapcheteConfigError(
                    "init zooms must be a subset of process zoom")
            return init_zooms
コード例 #28
0
ファイル: __init__.py プロジェクト: gijs/mapchete
    def _parse_config(self, input_config, single_input_file):
        # from configuration dictionary
        if isinstance(input_config, dict):
            raw = input_config
            mapchete_file = None
            try:
                config_dir = input_config["config_dir"]
            except KeyError:
                raise MapcheteConfigError("config_dir parameter missing")
        # from Mapchete file
        elif os.path.splitext(input_config)[1] == ".mapchete":
            with open(input_config, "r") as config_file:
                raw = yaml.load(config_file.read())
            mapchete_file = input_config
            config_dir = os.path.dirname(os.path.realpath(mapchete_file))
        # throw error if unknown object
        else:
            raise MapcheteConfigError(
                "Configuration has to be a dictionary or a .mapchete file.")
        # make sure old input_files parameter is converted correctly
        if "input_files" in raw and "input" in raw:
            raise MapcheteConfigError("Either 'input_files' or'input allowed")
        elif "input_files" in raw:
            warnings.warn(
                "'input_files' is deprecated and will be replaced by 'input'")
            raw["input"] = raw.pop("input_files")
        # check if mandatory parameters are provided
        for param in _MANDATORY_PARAMETERS:
            if param not in raw:
                raise MapcheteConfigError("%s parameter missing" % param)
        # pixelbuffer and metatiling
        raw["pixelbuffer"] = self._set_pixelbuffer(raw)
        raw["output"]["pixelbuffer"] = self._set_pixelbuffer(raw["output"])
        raw["metatiling"] = self._set_metatiling(raw)
        raw["output"]["metatiling"] = self._set_metatiling(
            raw["output"], default=raw["metatiling"])
        if not raw["metatiling"] >= raw["output"]["metatiling"]:
            raise MapcheteConfigError(
                "Process metatiles cannot be smaller than output metatiles.")
        # absolute output path
        raw["output"].update(path=os.path.normpath(
            os.path.join(config_dir, raw["output"]["path"])))
        # determine input files
        if raw["input"] == "from_command_line" and (self.mode in [
                "memory", "continue", "overwrite"
        ]):
            if not single_input_file:
                raise MapcheteConfigError(
                    "please provide an input file via command line")
            else:
                raw.update(input={"input_file": single_input_file})

        # return parsed configuration
        return raw, mapchete_file, config_dir
コード例 #29
0
ファイル: gtiff.py プロジェクト: Milk-oolong/mapchete
 def prepare(self, process_area=None, **kwargs):
     bounds = snap_bounds(
         bounds=Bounds(*process_area.intersection(
             box(*self.output_params["delimiters"]
                 ["effective_bounds"])).bounds),
         pyramid=self.pyramid,
         zoom=self.zoom) if process_area else self.output_params[
             "delimiters"]["effective_bounds"]
     height = math.ceil((bounds.top - bounds.bottom) /
                        self.pyramid.pixel_x_size(self.zoom))
     width = math.ceil((bounds.right - bounds.left) /
                       self.pyramid.pixel_x_size(self.zoom))
     logger.debug("output raster bounds: %s", bounds)
     logger.debug("output raster shape: %s, %s", height, width)
     self._profile = dict(
         GTIFF_DEFAULT_PROFILE,
         driver="GTiff",
         transform=Affine(self.pyramid.pixel_x_size(self.zoom), 0,
                          bounds.left, 0,
                          -self.pyramid.pixel_y_size(self.zoom),
                          bounds.top),
         height=height,
         width=width,
         count=self.output_params["bands"],
         crs=self.pyramid.crs,
         **{
             k: self.output_params.get(k, GTIFF_DEFAULT_PROFILE[k])
             for k in GTIFF_DEFAULT_PROFILE.keys()
         })
     logger.debug("single GTiff profile: %s", self._profile)
     if height * width > 20000 * 20000:
         raise ValueError("output GeoTIFF too big")
     # set up rasterio
     if path_exists(self.path):
         if self.output_params["mode"] != "overwrite":
             raise MapcheteConfigError(
                 "single GTiff file already exists, use overwrite mode to replace"
             )
         else:
             logger.debug("remove existing file: %s", self.path)
             os.remove(self.path)
     logger.debug("open output file: %s", self.path)
     self.rio_file = rasterio.open(self.path, "w+", **self._profile)
コード例 #30
0
    def __init__(self, input_params, **kwargs):
        """Initialize."""
        super(InputData, self).__init__(input_params, **kwargs)
        self._params = input_params["abstract"]

        # validate parameters
        validate_values(
            self._params, [
                ("path", six.string_types),
                ("type", six.string_types),
                ("extension", six.string_types)])
        if not self._params["extension"] in [
            "tif", "vrt", "png", "jpg", "mixed", "jp2", "geojson"
        ]:
            raise MapcheteConfigError(
                "invalid file extension given: %s" % self._params["extension"])
        self._ext = self._params["extension"]
        self.path = _absolute_path(
            input_params["conf_dir"], self._params["path"])

        # define pyramid
        self.td_pyramid = BufferedTilePyramid(
            self._params["type"],
            metatiling=self._params.get("metatiling", 1),
            tile_size=self._params.get("tile_size", 256),
            pixelbuffer=self._params.get("pixelbuffer", 0))

        # additional params
        self._bounds = self._params.get("bounds", self.td_pyramid.bounds)
        self._file_type = (
            "vector" if self._params["extension"] == "geojson" else "raster")
        if self._file_type == "raster":
            self._params["count"] = self._params.get(
                "count", self._params.get("bands", None))
            validate_values(self._params, [
                ("dtype", six.string_types),
                ("count", int)])
            self._profile = {
                "nodata": self._params.get("nodata", 0),
                "dtype": self._params["dtype"],
                "count": self._params["count"]}
        else:
            self._profile = None