123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- #
- # AUTHOR(S): Anna Petrasova <kratochanna AT gmail>
- #
- # PURPOSE: This module contains functionality for managing region
- # during rendering.
- #
- # COPYRIGHT: (C) 2021 Anna Petrasova, and by the GRASS Development Team
- #
- # This program is free software under the GNU General Public
- # License (>=v2). Read the file COPYING that comes with GRASS
- # for details.
- import grass.script as gs
- from grass.exceptions import CalledModuleError
- from .utils import (
- get_location_proj_string,
- get_region,
- reproject_region,
- get_map_name_from_d_command,
- )
- class RegionManagerForInteractiveMap:
- def __init__(self, use_region, saved_region, src_env, tgt_env):
- """Manages region during rendering for interactive map.
- :param use_region: if True, use either current or provided saved region,
- else derive region from rendered layers
- :param saved_region: if name of saved_region is provided,
- this region is then used for rendering
- :param src_env: source environment (original projection)
- :param tgt_env: target environment (pseudomercator)
- """
- self._use_region = use_region
- self._saved_region = saved_region
- self._src_env = src_env
- self._tgt_env = tgt_env
- self._bbox = [[90, 180], [-90, -180]]
- @property
- def bbox(self):
- """Bbox property for accessing maximum
- bounding box of all rendered layers.
- """
- return self._bbox
- def set_region_from_raster(self, raster):
- """Sets computational region for rendering.
- This functions sets computational region based on
- a raster map in the target environment.
- If user specified the name of saved region during object's initialization,
- the provided region is used. If it's not specified
- and use_region=True, current region is used.
- Also enlarges bounding box based on the raster.
- """
- if self._saved_region:
- self._src_env["GRASS_REGION"] = gs.region_env(
- region=self._saved_region, env=self._src_env
- )
- elif self._use_region:
- # use current
- self._set_bbox(self._src_env)
- return
- else:
- self._src_env["GRASS_REGION"] = gs.region_env(
- raster=raster, env=self._src_env
- )
- region = get_region(env=self._src_env)
- from_proj = get_location_proj_string(self._src_env)
- to_proj = get_location_proj_string(env=self._tgt_env)
- new_region = reproject_region(region, from_proj, to_proj)
- gs.run_command(
- "g.region",
- n=new_region["north"],
- s=new_region["south"],
- e=new_region["east"],
- w=new_region["west"],
- env=self._tgt_env,
- )
- self._set_bbox(self._src_env)
- def set_bbox_vector(self, vector):
- """Enlarge bounding box based on vector"""
- env = self._src_env.copy()
- env["GRASS_REGION"] = gs.region_env(vector=vector, env=env)
- self._set_bbox(env)
- def _set_bbox(self, env):
- bbox = gs.parse_command("g.region", flags="bg", env=env)
- s = float(bbox["ll_s"])
- w = float(bbox["ll_w"])
- n = float(bbox["ll_n"])
- e = float(bbox["ll_e"])
- if self._bbox[0][0] > s:
- self._bbox[0][0] = s
- if self._bbox[0][1] > w:
- self._bbox[0][1] = w
- if self._bbox[1][0] < n:
- self._bbox[1][0] = n
- if self._bbox[1][1] < e:
- self._bbox[1][1] = e
- class RegionManagerFor2D:
- def __init__(self, use_region, saved_region, env):
- """Manages region during rendering.
- :param use_region: if True, use either current or provided saved region,
- else derive region from rendered layers
- :param saved_region: if name of saved_region is provided,
- this region is then used for rendering
- :param env: environment for rendering
- """
- self._env = env
- self._use_region = use_region
- self._saved_region = saved_region
- self._extent_set = False
- self._resolution_set = False
- def set_region_from_env(self, env):
- """Copies GRASS_REGION from provided environment
- to local environment to set the computational region"""
- if "GRASS_REGION" in env:
- self._env["GRASS_REGION"] = env["GRASS_REGION"]
- def set_region_from_command(self, module, **kwargs):
- """Sets computational region for rendering.
- This functions identifies a raster/vector map from command
- and tries to set computational region based on that.
- It takes the extent from the first layer (raster or vector)
- and resolution and alignment from first raster layer.
- If user specified the name of saved region during object's initialization,
- the provided region is used. If it's not specified
- and use_region=True, current region is used.
- """
- if self._saved_region:
- self._env["GRASS_REGION"] = gs.region_env(
- region=self._saved_region, env=self._env
- )
- return
- if self._use_region:
- # use current
- return
- if self._resolution_set and self._extent_set:
- return
- name = get_map_name_from_d_command(module, **kwargs)
- if not name:
- return
- if len(name.split()) > 1:
- name = name.split()[0]
- try:
- if module.startswith("d.vect"):
- if not self._resolution_set and not self._extent_set:
- self._env["GRASS_REGION"] = gs.region_env(
- vector=name, env=self._env
- )
- self._extent_set = True
- else:
- if not self._resolution_set and not self._extent_set:
- self._env["GRASS_REGION"] = gs.region_env(
- raster=name, env=self._env
- )
- self._extent_set = True
- self._resolution_set = True
- elif not self._resolution_set:
- self._env["GRASS_REGION"] = gs.region_env(align=name, env=self._env)
- self._resolution_set = True
- except CalledModuleError:
- return
- class RegionManagerFor3D:
- def __init__(self, use_region, saved_region):
- """Manages region during rendering.
- :param use_region: if True, use either current or provided saved region,
- else derive region from rendered layers
- :param saved_region: if name of saved_region is provided,
- this region is then used for rendering
- """
- self._use_region = use_region
- self._saved_region = saved_region
- def set_region_from_command(self, env, **kwargs):
- """Sets computational region for rendering.
- This functions identifies a raster map from m.nviz.image command
- and tries to set computational region based on that.
- If user specified the name of saved region during object's initialization,
- the provided region is used. If it's not specified
- and use_region=True, current region is used.
- """
- if self._saved_region:
- env["GRASS_REGION"] = gs.region_env(region=self._saved_region, env=env)
- return
- if self._use_region:
- # use current
- return
- if "elevation_map" in kwargs:
- elev = kwargs["elevation_map"].split(",")[0]
- try:
- env["GRASS_REGION"] = gs.region_env(raster=elev, env=env)
- except CalledModuleError:
- return
|