import math
import gws
import gws.gis.extent
import gws.tools.units as units
import gws.types as t
#:export
[docs]class MapRenderView(t.Data):
bounds: t.Bounds
center: t.Point
dpi: int
rotation: int
scale: int
size_mm: t.Size
size_px: t.Size
[docs]def pixel_viewbox(view: t.MapRenderView):
"""Compute the pixel viewBox for a view"""
trans = pixel_transformer(view)
ext = view.bounds.extent
a = trans(ext[0], ext[1])
b = trans(ext[2], ext[3])
return [0, 0, b[0] - a[0], a[1] - b[1]]
[docs]def from_center(crs: t.Crs, center: t.Point, scale: int, out_size: t.Size, out_size_unit: str, rotation=0, dpi=0):
"""Create a view based on a center point"""
view = _base(out_size, out_size_unit, rotation, dpi)
view.center = center
view.scale = scale
# @TODO assuming projection units are 'm'
unit_per_mm = scale / 1000.0
w = units.px2mm(view.size_px[0], view.dpi)
h = units.px2mm(view.size_px[1], view.dpi)
ext = [
view.center[0] - (w * unit_per_mm) / 2,
view.center[1] - (h * unit_per_mm) / 2,
view.center[0] + (w * unit_per_mm) / 2,
view.center[1] + (h * unit_per_mm) / 2,
]
view.bounds = t.Bounds(crs=crs, extent=ext)
return view
[docs]def from_bbox(crs: t.Crs, bbox: t.Extent, out_size: t.Size, out_size_unit: str, rotation=0, dpi=0):
"""Create a view based on a bounding box"""
view = _base(out_size, out_size_unit, rotation, dpi)
view.center = [
bbox[0] + (bbox[2] - bbox[0]) / 2,
bbox[1] - (bbox[3] - bbox[1]) / 2,
]
view.scale = units.res2scale((bbox[2] - bbox[0]) / view.size_px[0])
view.bounds = t.Bounds(crs=crs, extent=bbox)
return view
def _base(out_size, out_size_unit, rotation, dpi):
view = t.MapRenderView()
view.dpi = max(units.OGC_SCREEN_PPI, int(dpi))
view.rotation = rotation
if out_size_unit == 'px':
view.size_px = out_size
view.size_mm = units.point_px2mm(out_size, view.dpi)
if out_size_unit == 'mm':
view.size_mm = out_size
view.size_px = units.point_mm2px(out_size, view.dpi)
return view