Skip to content
Snippets Groups Projects
Unverified Commit 1697270b authored by Jay Laura's avatar Jay Laura Committed by GitHub
Browse files

Merge pull request #112 from jlaura/proj

Updates proj to use pipelines.
parents 4331e975 9888d988
No related branches found
No related tags found
No related merge requests found
# Changelog
All changes that impact users of this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
<!---
This document is intended for users of the applications and API. Changes to things
like tests should not be noted in this document.
When updating this file for a PR, add an entry for your change under Unreleased
and one of the following headings:
- Added - for new features.
- Changed - for changes in existing functionality.
- Deprecated - for soon-to-be removed features.
- Removed - for now removed features.
- Fixed - for any bug fixes.
- Security - in case of vulnerabilities.
If the heading does not yet exist under Unreleased, then add it as a 3rd heading,
with three #.
When preparing for a public release candidate add a new 2nd heading, with two #, under
Unreleased with the version number and the release date, in year-month-day
format. Then, add a link for the new version at the bottom of this document and
update the Unreleased link so that it compares against the latest release tag.
When preparing for a bug fix release create a new 2nd heading above the Fixed
heading to indicate that only the bug fixes and security fixes are in the bug fix
release.
-->
## Unreleased
### Changed
- Removed all `pyproj` calls from csm.py, abstracting them into the reprojection and pyproj.Transformer code inside utils.py. Updated the transformations to use the new pipeline style syntax to avoid deprecation warnings about old syntax.p
...@@ -6,13 +6,13 @@ from csmapi import csmapi ...@@ -6,13 +6,13 @@ from csmapi import csmapi
import jinja2 import jinja2
from osgeo import ogr from osgeo import ogr
import numpy as np import numpy as np
import pyproj
import requests import requests
import scipy.stats import scipy.stats
from functools import singledispatch from functools import singledispatch
from plio.io.io_gdal import GeoDataset from plio.io.io_gdal import GeoDataset
from knoten import utils
class NumpyEncoder(json.JSONEncoder): class NumpyEncoder(json.JSONEncoder):
def default(self, obj): def default(self, obj):
if isinstance(obj, np.ndarray): if isinstance(obj, np.ndarray):
...@@ -157,10 +157,16 @@ def _(dem, image_pt, camera, max_its = 20, tolerance = 0.001): ...@@ -157,10 +157,16 @@ def _(dem, image_pt, camera, max_its = 20, tolerance = 0.001):
intersection = generate_ground_point(0.0, image_pt, camera) intersection = generate_ground_point(0.0, image_pt, camera)
iterations = 0 iterations = 0
semi_major, semi_minor = get_radii(camera) semi_major, semi_minor = get_radii(camera)
ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor) source_proj = f'+proj=cart +a={semi_major} +b={semi_minor}'
dest_proj = f'+proj=lonlat +a={semi_major} +b={semi_minor}'
transformer = utils.create_transformer(source_proj, dest_proj)
while iterations != max_its: while iterations != max_its:
lon, lat, alt = pyproj.transform(ecef, lla, intersection.x, intersection.y, intersection.z) lon, lat, alt = transformer.transform(intersection.x,
intersection.y,
intersection.z,
errcheck=True)
px, py = dem.latlon_to_pixel(lat, lon) px, py = dem.latlon_to_pixel(lat, lon)
height = dem.read_array(1, [px, py, 1, 1])[0][0] height = dem.read_array(1, [px, py, 1, 1])[0][0]
...@@ -231,8 +237,9 @@ def generate_latlon_boundary(camera, boundary, dem=0.0, radii=None, **kwargs): ...@@ -231,8 +237,9 @@ def generate_latlon_boundary(camera, boundary, dem=0.0, radii=None, **kwargs):
else: else:
semi_major, semi_minor = radii semi_major, semi_minor = radii
ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor) source_proj = f'+proj=cart +a={semi_major} +b={semi_minor}'
lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor) dest_proj = f'+proj=lonlat +a={semi_major} +b={semi_minor}'
transformer = utils.create_transformer(source_proj, dest_proj)
gnds = np.empty((len(boundary), 3)) gnds = np.empty((len(boundary), 3))
...@@ -245,7 +252,7 @@ def generate_latlon_boundary(camera, boundary, dem=0.0, radii=None, **kwargs): ...@@ -245,7 +252,7 @@ def generate_latlon_boundary(camera, boundary, dem=0.0, radii=None, **kwargs):
gnds[i] = [gnd.x, gnd.y, gnd.z] gnds[i] = [gnd.x, gnd.y, gnd.z]
lons, lats, alts = pyproj.transform(ecef, lla, gnds[:,0], gnds[:,1], gnds[:,2]) lons, lats, alts = transformer.transform(gnds[:,0], gnds[:,1], gnds[:,2])
return lons, lats, alts return lons, lats, alts
def generate_gcps(camera, boundary, radii=None): def generate_gcps(camera, boundary, radii=None):
...@@ -392,16 +399,16 @@ def generate_bodyfixed_footprint(camera, boundary, radii=None): ...@@ -392,16 +399,16 @@ def generate_bodyfixed_footprint(camera, boundary, radii=None):
latlon_fp = generate_latlon_footprint(camera, boundary, radii=radii) latlon_fp = generate_latlon_footprint(camera, boundary, radii=radii)
ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor) source_proj = f'+proj=lonlat +a={semi_major} +b={semi_minor}'
lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor) dest_proj = f'+proj=cart +a={semi_major} +b={semi_minor}'
transformer = utils.create_transformer(source_proj, dest_proj)
# Step over all geometry objects in the latlon footprint # Step over all geometry objects in the latlon footprint
for i in range(latlon_fp.GetGeometryCount()): for i in range(latlon_fp.GetGeometryCount()):
latlon_coords = np.array(latlon_fp.GetGeometryRef(i).GetGeometryRef(0).GetPoints()) latlon_coords = np.array(latlon_fp.GetGeometryRef(i).GetGeometryRef(0).GetPoints())
# Check if the geometry object is populated with points # Check if the geometry object is populated with points
if len(latlon_coords) > 0: if len(latlon_coords) > 0:
x, y, z = pyproj.transform(lla, ecef, latlon_coords[:,0], latlon_coords[:,1], latlon_coords[:,2]) x, y, z = transformer.transform(latlon_coords[:,0], latlon_coords[:,1], latlon_coords[:,2])
# Step over all coordinate points in a geometry object and update said point # Step over all coordinate points in a geometry object and update said point
for j, _ in enumerate(latlon_coords): for j, _ in enumerate(latlon_coords):
......
...@@ -35,9 +35,17 @@ def reproject(record, semi_major, semi_minor, source_proj, dest_proj, **kwargs): ...@@ -35,9 +35,17 @@ def reproject(record, semi_major, semi_minor, source_proj, dest_proj, **kwargs):
Transformed coordinates as y, x, z Transformed coordinates as y, x, z
""" """
source_pyproj = pyproj.Proj(proj = source_proj, a = semi_major, b = semi_minor) transformer = pyproj.Transformer.from_crs(f'+proj={source_proj} +a={semi_major} +b={semi_minor}',
dest_pyproj = pyproj.Proj(proj = dest_proj, a = semi_major, b = semi_minor) f'+proj={dest_proj} +a={semi_major} +b={semi_minor}',
always_xy=True)
y, x, z = pyproj.transform(source_pyproj, dest_pyproj, record[0], record[1], record[2], **kwargs) source_proj = f'+proj={source_proj} +a={semi_major} +b={semi_minor}'
dest_proj = f'+proj={dest_proj} +a={semi_major} +b={semi_minor}'
transformer = create_transformer(source_proj, dest_proj)
x, y, z = transformer.transform(record[0], record[1], record[2], errcheck=True)
return y, x, z return y, x, z
def create_transformer(source_proj, dest_proj):
return pyproj.Transformer.from_crs(source_proj,
dest_proj,
always_xy=True)
\ No newline at end of file
...@@ -4,7 +4,8 @@ import pytest ...@@ -4,7 +4,8 @@ import pytest
from knoten import utils from knoten import utils
def test_reproject(): def test_reproject():
with mock.patch('pyproj.transform', return_value=[1,1,1]) as mock_pyproj: res = utils.reproject([0,1,0], 10, 10, 'geocent', 'latlon')
res = utils.reproject([1,1,1], 10, 10, 'geocent', 'latlon') print(res)
mock_pyproj.assert_called_once() assert res[0] == 0
assert res == (1,1,1) assert res[1] == 90
assert res[2] == -9
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment