Topo - Transform a profile from a local to cartographic coordinates

O.KAUFMANN, 2020, 2021.

[1]:
import matplotlib.pyplot as plt
import numpy as np
from shapely.geometry import Point, LineString, Polygon
from shapely.affinity import translate, rotate, scale, skew, affine_transform
[2]:
from bootsoff.topo.geometry import plot_profile
[3]:
# profile extremities in local coordinates
profile_start_local = Point([40., 70.])
profile_end_local = Point([90., 120.])
markers_along_profile_local = [Point([55., 75.]), Point([60., 98.]), Point([80.,110.])]

# profile extremities in cartographic coordinates
profile_start_map = Point([98227, 87122])
profile_end_map = Point([98247, 87084])

Profile in local coordinates (extremities and eventual markers)

[4]:
profile = [profile_start_local]
profile.extend(markers_along_profile_local)
profile.extend([profile_end_local])
profile_local = LineString(profile)
[5]:
plot_profile(obj=profile_local, name='P1')
plt.gca().set_title('Local');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_6_0.png

Profile extremities in map coordinates

[6]:
profile_map = LineString([profile_start_map, profile_end_map])
[7]:
plot_profile(obj=profile_map, name='P1')
plt.gca().set_title('Cartographic');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_9_0.png

The transform consists in:

  • A translation to move the start point of the profile to the origin of the local system -> t1

  • A rotation to align the profile on the orientation of the profile in the map (cartographic) coordinates -> r

  • A scaling (should be close to 1 if units are the same) to accomodate for differences in length -> s

  • A translation to bring the start of the profile at its position in the map coordinates -> t2

Left and right plots show the profile before and after each transformations

Translating

[8]:
t1 = translate(profile_local, xoff=-profile_local.coords[0][0], yoff=-profile_local.coords[0][1])
[9]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=profile_local, name='P1')
plot_profile(ax=ax[1], obj=t1, name='P1')
ax[0].set_title('Local')
ax[1].set_title('Translated');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_13_0.png

Rotating

[10]:
theta_local = np.arctan2(profile_local.coords[-1][1]-profile_local.coords[0][1],
                   profile_local.coords[-1][0]-profile_local.coords[0][0])
theta_map = np.arctan2(profile_map.coords[-1][1]-profile_map.coords[0][1],
                   profile_map.coords[-1][0]-profile_map.coords[0][0])
r = rotate(t1, angle=theta_map-theta_local, origin = (0.,0.), use_radians=True)
[11]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=t1, name='P1')
plot_profile(ax=ax[1], obj=r, name='P1')
ax[0].set_title('Translated')
ax[1].set_title('Rotated');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_16_0.png

Scaling

[12]:
scale_factor = (profile_map.length/profile_local.length)
s = scale(r, xfact=scale_factor, yfact=scale_factor,  origin=(0.,0.))
[13]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=r, name='P1')
plot_profile(ax=ax[1], obj=s, name='P1')
ax[0].set_title('Rotated')
ax[1].set_title('Scaled');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_19_0.png

Translating

[14]:
t2 = translate(s, xoff=profile_map.coords[0][0], yoff=profile_map.coords[0][1])
[15]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=s, name='P1')
plot_profile(ax=ax[1], obj=t2, name='P1')
ax[0].set_title('Scaled')
ax[1].set_title('Cartographic');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_22_0.png

Transform sum up

[16]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=profile_local, name='P1')
plot_profile(ax=ax[1], obj=t2, name='P1')
stepsize=10.
ax[0].set_title('Local')
ax[1].set_title('Cartographic');
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_24_0.png

All in one alternative

[17]:
import bootsoff.topo.geometry as btg
[18]:
from_obj = profile_local
to_obj = profile_map
[19]:
tranform_matrix = btg.transform_matrix_2d(from_obj, to_obj, shapely_format=True)
(40.0, 70.0, 90.0, 120.0) (98227.0, 87122.0, 98247.0, 87084.0)
[20]:
transformed_profile = affine_transform(profile_local, tranform_matrix)
[21]:
fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10,4))
plot_profile(ax=ax[0], obj=t2, name='P1')
plot_profile(ax=ax[1], obj=transformed_profile, name='P1')
stepsize=10.
ax[0].set_title('Step by step')
ax[0].grid('on')
ax[1].set_title('All in one');
ax[1].grid('on')
../../_images/examples_basic_Topo_-_Transform_profile_from_local_to_cartographic_coordinates_31_0.png