Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 84 additions & 37 deletions docs/pvcollada_coordinate_transformation_with_diagram.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

# PVCollada Coordinate Transformation Guide
# Guide to Coordinates and Coordinate Transformations

## ENU Coordinate Frame

Expand All @@ -14,44 +14,31 @@ latitude, longitude and altitude stored in the COLLADA document.

## Example Geometry

Cube definition in local coordinates:
We'll illustrate coordinates and transformations using a cube defined in PVCollada's local coordinates:

- lower corner `(1,1,1)`
- size `(3,2,1)`

Assume that the topocentric coordinate origin is at the this geolocation:
![PVCollada cube](pvcollada_cube_diagram.png)


## From Local ENU to Geographic Coordinates

Assume that the topocentric coordinate origin is at this geolocation in the WGS84 datum:

- Albuquerque, NM, USA
- Latitude `35.0845`
- Longitude `-106.651`
- Altitude `1619`
- Projection `EPSG:32613`

## Diagram

![PVCollada cube](pvcollada_cube_diagram.png)

The diagram shows the cube in the local coordinate system along with the ENU axes.
- Projection `EPSG:4326`

## Computed Geographic Coordinates
EPSG:4326 is the identifier for the WGS-84 geographic coordinate system.

The geocoordinate of the cube are computed using the python library pymap3d.
The WGS-84 geocoordinates of the cube can be computed using either the pymap3d or pyproj.

| x | y | z | latitude | longitude | altitude |
|-----------:|-----------:|-----------:|------------:|--------------:|--------------:|
| 1.00000000 | 1.00000000 | 1.00000000 | 35.08450901 | -106.65098904 | 1620.00000016 |
| 4.00000000 | 1.00000000 | 1.00000000 | 35.08453605 | -106.65098904 | 1620.00000134 |
| 1.00000000 | 3.00000000 | 1.00000000 | 35.08450901 | -106.65096711 | 1620.00000078 |
| 4.00000000 | 3.00000000 | 1.00000000 | 35.08453605 | -106.65096711 | 1620.00000196 |
| 1.00000000 | 1.00000000 | 2.00000000 | 35.08450901 | -106.65098904 | 1621.00000016 |
| 4.00000000 | 1.00000000 | 2.00000000 | 35.08453605 | -106.65098904 | 1621.00000134 |
| 1.00000000 | 3.00000000 | 2.00000000 | 35.08450901 | -106.65096711 | 1621.00000078 |
| 4.00000000 | 3.00000000 | 2.00000000 | 35.08453605 | -106.65096711 | 1621.00000196 |

## Python Examples
### Using pymap3d

```python
# Using pymap3d

import pandas as pd
import pymap3d as pm
Expand All @@ -61,7 +48,7 @@ lon0 = -106.651
alt0 = 1619.0

# Local coordinates of corners of the cube
coords = pd.DataFrame(
topocentric_coords = pd.DataFrame(
columns=['x', 'y', 'z'],
data=[[1., 1., 1.],
[4., 1., 1.],
Expand All @@ -74,21 +61,35 @@ coords = pd.DataFrame(
)

# Translate the cube to geocoordinates
# pymap3d.enu2geodetic uses WGS-84 by default. We'll specify a datum to show how
# it is done.

datum = pm.Ellipsoid.from_name('wgs84')

lat, lon, alt = pm.enu2geodetic(coords['y'], coords['x'], coords['z'],
lat0, lon0, alt0)
lat0, lon0, alt0, ell=datum)

coords['lat'] = lat
coords['lon'] = lon
coords['alt'] = alt
geodetic_coords = pd.DataFrame({'lat': lat, 'lon': lon, 'alt': alt})

print('Topocentric to Geodetic coordinates')
print(coords.to_markdown(index=False))
print('Topocentric to Geodetic coordinates using pymap3d')
print(geodetic_coords.to_markdown(index=False, floatfmt=".8f"))

```
Topocentric to Geodetic coordinates using pymap3d
| lat | lon | alt |
|------------:|--------------:|--------------:|
| 35.08450901 | -106.65098904 | 1620.00000016 |
| 35.08453605 | -106.65098904 | 1620.00000134 |
| 35.08450901 | -106.65096711 | 1620.00000078 |
| 35.08453605 | -106.65096711 | 1620.00000196 |
| 35.08450901 | -106.65098904 | 1621.00000016 |
| 35.08453605 | -106.65098904 | 1621.00000134 |
| 35.08450901 | -106.65096711 | 1621.00000078 |
| 35.08453605 | -106.65096711 | 1621.00000196 |

### Using pyproj

```python
# Using pyproj

import pandas as pd
import pyproj
Expand Down Expand Up @@ -132,11 +133,57 @@ coords = pd.DataFrame(
lon, lat, alt = transformer.transform(
coords['x'], coords['y'], coords['z'])

coords['latitude'] = lat
coords['longitude'] = lon
coords['altitude'] = alt
geodetic_coords = pd.DataFrame({'lat': lat, 'lon': lon, 'alt': alt})

print('Topocentric to Geodetic coordinates using pymap3d')
print(geodetic_coords.to_markdown(index=False, floatfmt=".8f"))

```

## From Geographic or Projected Coordinates to PVCollada ENU

We'll show how we can reverse the above transformation, from WGS-84 geographic coordinates to PVCollada's ENU coordinates,
using either pymap3d or pyproj.

### Using pymap3d

print('Topocentric to Geodetic coordinates')
```python

import numpy as np
import pandas as pd
import pymap3d as pm


geocoords = pd.DataFrame(
columns=['lat', 'lon', 'alt'],
data = np.array(
[[35.08450901, -106.65098904, 1620.00000016],
[35.08453605, -106.65098904, 1620.00000134],
[35.08450901, -106.65096711, 1620.00000078],
[35.08453605, -106.65096711, 1620.00000196],
[35.08450901, -106.65098904, 1621.00000016],
[35.08453605, -106.65098904, 1621.00000134],
[35.08450901, -106.65096711, 1621.00000078],
[35.08453605, -106.65096711, 1621.00000196]]
)
)

# origin of ENU coordinates
lat0 = 35.0845
lon0 = -106.651
alt0 = 1619.0
datum = pm.Ellipsoid.from_name('wgs84')

x, y, z = pm.geodetic2enu(
geocoords['lat'], geocoords['lon'], geocoords['alt'],
lat0, lon0, alt0, ell=datum
)

# put x, y, z into a DataFrame for convenient printing
enucoords = pd.DataFrame({'x': x, 'y': y, 'z': z})

print('Geodetic to Topocentric coordinates using pymap3d')
print(coords.to_markdown(index=False, floatfmt=".8f"))

```