[R-sig-Geo] Height transformation (ellipsoidal to EGM2008)

Roger Bivand Roger@B|v@nd @end|ng |rom nhh@no
Thu Jul 28 13:38:27 CEST 2022


On Tue, 26 Jul 2022, inti luna wrote:

> Hi all,
> I have a table with data points with CRS EPSG 4326 and ellipsoidal height
> (m) and would like to transform it to another CRS. Target horizontal is
> EPSG: 25831 and target height is based on EGM2008 (EPSG 3855).
>
> I have carried the horizontal transformation with the sf package but I
> don´t know how to perform the height transformation. Any guidance is
> appreciated. I have been checking
> https://eur02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fkeen-swartz-3146c4.netlify.app%2Fsf.html%23st_transform-sf_project&data=05%7C01%7CRoger.Bivand%40nhh.no%7Cccb34858b29945e7edb508da6f71f01d%7C33a15b2f849941998d56f20b5aa91af2%7C0%7C0%7C637944834193544665%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000%7C%7C%7C&sdata=tSwZgNFNWpnn5%2BeFWpyUUDSxws7QGYbSi%2Bn3G7GywkI%3D&reserved=0 but
> still have not found information about height transformation

No, this is much more complex. Please read

https://proj.org/apps/cs2cs.html

to begin with (not self-explanatory but accurate). R does not provide PROJ 
apps, but running on my Linux machine (PROJ 9.0.1, but 7.2.1 is fine):

$ export PROJ_NETWORK=ON
$ echo 2.32152788 41.75758799 1235.577 | cs2cs EPSG:4326 
EPSG:25831+EPSG:3855
5182922.95	329657.82 1264.66
$ export PROJ_NETWORK=OFF
$ echo 2.32152788 41.75758799 1235.577 | cs2cs EPSG:4326 
EPSG:25831+EPSG:3855
5182922.95	329657.82 1235.58

When the CDN network is ON, us_nga_egm08_25.tif is available for grid 
transformation in 3D. When off, it is not:

$ projinfo -o PROJ -s EPSG:4326 -t EPSG:25831+EPSG:3855

gives a lot of output  describing all of the transformation operations 
that might be possible if known grids are available.

Starting R with the CDN ON:

$ PROJ_NETWORK=ON R
...
library(sf)
o <- sf_proj_pipelines("EPSG:4326", "EPSG:25831+EPSG:3855")
o

o[1,] is the best than can be instantiated with:

+proj=pipeline
  +step +proj=unitconvert +xy_in=deg +xy_out=rad
  +step +inv +proj=vgridshift +grids=us_nga_egm08_25.tif +multiplier=1
  +step +proj=utm +zone=31 +ellps=GRS80

so now making a vertical shift using a grid from the CDN.

Creating your data.points (thanks for a good reprex!) but naming 
"Ellipsoidal_height" as the third coordinate:

data.points <- st_as_sf(data1, coords = c("Longitude", "Latitude",
   "Ellipsoidal_height"))

I get:

data.points2<-st_transform(data.points, "EPSG:25831")
data.points2$geometry
First 5 geometries:
POINT Z (443597.6 4623084 1235.577)

which is wierd, but using the pipeline found above:

data.points2a<-st_transform(data.points, "EPSG:25831",
  pipeline=o$definition[1])
data.points2a$geometry

giving

POINT Z (5182923 329657.8 1264.658)

as in the PROJ app.

One point is that you need either to install the grid locally, or enable 
the CDN *before* you start R and load sf.

Another is that sf_proj_pipelines() uses PROJ directly, so can identify 
combined pipelines, but st_transform() uses PROJ via GDAL, and doesn't 
handle this correctlly, so one must pass the pipeline. The output CRS will 
also be wrong, it should be:

COMPOUNDCRS["ETRS89 / UTM zone 31N + EGM2008 height", ...

not

PROJCRS["ETRS89 / UTM zone 31N", ... .

Finally, your sf object needed the third coordinate defined, otherwise it 
had no idea that it wasn't 2D.

Consider creating an sf issue, and if possible contact others needing 
vertical transformation and consider contributing a blog or vignette. Both 
sf and terra need user input to document important topics like this.

Best wishes,

Roger


>
> Repex
>
> library(sf)
>
> #create sample dataset
>
> data1<-"Name,Longitude,Latitude,Ellipsoidal_height
> gcp1,2.32152788,41.75758799,1235.577
> gcp2,2.32129905,41.75757489,1234.38
> gcp3,2.3212163,41.75760007,1233.49
> gcp4,2.32165884,41.75765011,1235.785
> gcp5,2.32163868,41.75764588,1235.741
> gcp6,2.32167394,41.75793979,1236.763
> gcp7,2.32118573,41.75769993,1232.364
> gcp8,2.32115307,41.75770638,1231.897
> gcp9,2.32097163,41.75779261,1228.454"
>
> data1<-read.table(text = data1, header = T,sep = ",")
> head(data1)
> str(data1)
>
> sf::sf_extSoftVersion()
>
> crs_epsg25831 <- st_crs(25831)
> crs_epsg25831
>
> data.points <- st_as_sf(data1, coords = c("Longitude", "Latitude"))
> st_crs(data.points) <- 4326
> data.points
>
> #transform from EPSG 4326 to EPSG 25831(ETRS89/UTM 31N)
> data.points2<-st_transform(data.points,crs_epsg25831)
>
> st_crs(data.points2)
> data.points2
> data.points2$geometry
> write.csv(data.points2, "sample.points_epsg25831.csv")
>
> # height transformation ?
>
>
> Machine and software details:
>
> OS: Windows
> R: version 4.2.1 (2022-06-23 ucrt) -- "Funny-Looking Kid"
> Rstudio: RStudio 2022.07.1+554 "Spotted Wakerobin" Release
> (7872775ebddc40635780ca1ed238934c3345c5de, 2022-07-22) for Windows
> Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like
> Gecko) QtWebEngine/5.12.8 Chrome/69.0.3497.128 Safari/537.36
>
> GEOS: 3.9.1
> GDAL 3.4.3
> PROJ 7.2.1
> sf_use_s2: TRUE
>
>
>
> Kind regards,
> Inti Luna
>
>

-- 
Roger Bivand
Emeritus Professor
Department of Economics, Norwegian School of Economics,
Postboks 3490 Ytre Sandviken, 5045 Bergen, Norway.
e-mail: Roger.Bivand using nhh.no
https://orcid.org/0000-0003-2392-6140
https://scholar.google.no/citations?user=AWeghB0AAAAJ&hl=en


More information about the R-sig-Geo mailing list