Skip to content

Commit

Permalink
> 0.23.4
Browse files Browse the repository at this point in the history
- overview.nav_plot.create_figure function: reproject background image to latlon by default
  • Loading branch information
peter-urban committed Jul 29, 2024
1 parent e76c0b6 commit e49d001
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 5 deletions.
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ project(
'cpp',
license: 'MPL-2.0',

version: '0.8.0',
version: '0.8.1',
default_options: ['warning_level=2', 'buildtype=release', 'cpp_std=c++20'],
meson_version: '>=1.3.2' #first version with clang-cl openmp support
)
Expand Down
39 changes: 39 additions & 0 deletions python/tests/overview/test_navplot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import themachinethatgoesping as Ping
import rasterio as rio
import os

class TestNavPlot:
"""
This class contains unit tests for navigation plot functions.
"""

def test_create_figure_background_image_projection(self):
src_utm = '../../../unittest_data/background_maps/test_utm.tiff' # map in UTM projection EPSG:32631
src_latlon = '../../../unittest_data/background_maps/test_latlon.tiff' # map in latlon projection EPSG:4326

src_utm = os.path.join(os.path.dirname(__file__), src_utm)
src_latlon = os.path.join(os.path.dirname(__file__), src_latlon)

# default projection should be EPSG:4326
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_latlon, return_crs=True)
assert crs == rio.crs.CRS.from_epsg(4326)

# utm should be converted to default projection EPSG:4326
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_utm, return_crs=True)
assert crs == rio.crs.CRS.from_epsg(4326)

# if dst_crs is set to None, default projecttion should be preserved
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_latlon, return_crs=True, dst_crs = None)
assert crs == rio.crs.CRS.from_epsg(4326)

# if dst_crs is set to None, default projecttion should be preserved
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_utm, return_crs=True, dst_crs = None)
assert crs == rio.crs.CRS.from_epsg(32631)

# if dst_crs is set to another projection, this projection should be used
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_latlon, return_crs=True, dst_crs = 'EPSG:32631')
assert crs == rio.crs.CRS.from_epsg(32631)

# if dst_crs is set to another projection, this projection should be used
_,_,crs = Ping.pingprocessing.overview.nav_plot.create_figure('nav', background_image_path=src_utm, return_crs=True, dst_crs = 'EPSG:32631')
assert crs == rio.crs.CRS.from_epsg(32631)
60 changes: 56 additions & 4 deletions python/themachinethatgoesping/pingprocessing/overview/nav_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,50 @@
from matplotlib import pyplot as plt

import rasterio.plot as rioplt
import rasterio.warp as riowarp
import rasterio as rio
from rasterio.io import MemoryFile
from contextlib import contextmanager

from themachinethatgoesping.pingprocessing.core.progress import get_progress_iterator

#Adapted from: https://gis.stackexchange.com/questions/443822/how-do-you-reproject-a-raster-using-rasterio-in-memory
@contextmanager
def reproject_raster(src, dst_crs):

src_crs = src.crs
transform, width, height = riowarp.calculate_default_transform(src_crs, dst_crs, src.width, src.height, *src.bounds)
kwargs = src.meta.copy()

kwargs.update({
'crs': dst_crs,
'transform': transform,
'width': width,
'height': height})

with MemoryFile() as memfile:
with memfile.open(**kwargs) as dst:
for i in range(1, src.count + 1):
riowarp.reproject(
source=rio.band(src, i),
destination=rio.band(dst, i),
src_transform=src.transform,
src_crs=src.crs,
dst_transform=transform,
dst_crs=dst_crs,
resampling=riowarp.Resampling.nearest)
with memfile.open() as dataset: # Reopen as DatasetReader
yield dataset # Note yield not return as we're a contextmanager


def create_figure(
name: str, aspect: str = "equal", close_plots: bool = True, background_image_path: str = None, **kwargs
name: str,
aspect: str = "equal",
close_plots: bool = True,
background_image_path: str = None,
dst_crs = 'EPSG:4326',
return_crs = False,
**kwargs
) -> Tuple[plt.Figure, plt.Axes]:
"""
Create a figure with a given name and aspect ratio.
Expand All @@ -38,17 +75,32 @@ def create_figure(

# initialize axis
ax.grid(True, linestyle="--", color="gray", alpha=0.5)
ax.set_xlabel("longitude")
ax.set_ylabel("latitude")
ax.set_title(name)
ax.set_aspect(aspect)

if background_image_path:
background_map = rio.open(background_image_path)
_kwargs = {"cmap": "Greys_r"}
_kwargs.update(kwargs)
rioplt.show(background_map, ax=ax, **_kwargs)


if dst_crs is None or dst_crs == background_map.crs:
rioplt.show(background_map, ax=ax, **_kwargs)
dst_crs = background_map.crs
else:
with reproject_raster(background_map, dst_crs) as reprojected_map:
rioplt.show(reprojected_map, ax=ax, **_kwargs)
dst_crs = reprojected_map.crs

if dst_crs.is_geographic:
ax.set_xlabel("longitude")
ax.set_ylabel("latitude")
elif dst_crs.is_projected:
ax.set_xlabel("easting")
ax.set_ylabel("northing")

if return_crs:
return fig, ax, dst_crs
return fig, ax


Expand Down
Binary file added unittest_data/background_maps/test_latlon.tiff
Binary file not shown.
Binary file added unittest_data/background_maps/test_utm.tiff
Binary file not shown.

0 comments on commit e49d001

Please sign in to comment.