Skip to content

Commit ea146fa

Browse files
opatutbehrisch
authored andcommitted
netconvert: read --heightmap.geotiff spatial reference and transform coordinates for lookup
This adds support for geotiff input data in UTM projection, among others, and avoids an additional step to reproject the geotiff data to WGS84 (by using `gdalwarp`, for example), which adds a resampling step that introduces inaccuracy.
1 parent 4b66698 commit ea146fa

File tree

2 files changed

+48
-9
lines changed

2 files changed

+48
-9
lines changed

src/netbuild/NBHeightMapper.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,28 @@ NBHeightMapper::getZ(const Position& geo) const {
9292
const Boundary& boundary = item.boundary;
9393
float* raster = item.raster;
9494
double result = -1e6;
95-
if (boundary.around2D(geo)) {
95+
96+
double x = geo.x();
97+
double y = geo.y();
98+
99+
#ifdef HAVE_GDAL
100+
// Transform geo coordinates to the coordinate system of this
101+
// raster image for lookup in its raster, if applicable.
102+
if (item.transform != nullptr) {
103+
// Since the input coordinates are always WGS84 (they may be
104+
// transformed to it in NBNetBuilder::transformCoordinate), and
105+
// WGS84 uses latitude-longitude order (y-x), we have to swap the
106+
// input coordinates here.
107+
std::swap(x, y);
108+
109+
item.transform->Transform(1, &x, &y);
110+
}
111+
#endif
112+
113+
if (boundary.around2D(x, y)) {
96114
const int xSize = item.xSize;
97-
const double normX = (geo.x() - boundary.xmin()) / mySizeOfPixel.x();
98-
const double normY = (geo.y() - boundary.ymax()) / mySizeOfPixel.y();
115+
const double normX = (x - boundary.xmin()) / mySizeOfPixel.x();
116+
const double normY = (y - boundary.ymax()) / mySizeOfPixel.y();
99117
PositionVector corners;
100118
corners.push_back(Position(floor(normX) + 0.5, floor(normY) + 0.5, raster[(int)normY * xSize + (int)normX]));
101119
if (normX - floor(normX) > 0.5) {
@@ -332,17 +350,28 @@ NBHeightMapper::loadTiff(const std::string& file) {
332350
min = MIN2(min, (double)raster[i]);
333351
max = MAX2(max, (double)raster[i]);
334352
}
353+
354+
// Make a copy, GDALClose will destroy the original
355+
OGRSpatialReference spatialRef(*poDataset->GetSpatialRef());
356+
335357
GDALClose(poDataset);
358+
336359
if (ok) {
337360
WRITE_MESSAGE("Read geotiff heightmap with size " + toString(xSize) + "," + toString(ySize)
338361
+ " for geo boundary [" + toString(boundary)
339362
+ "] with elevation range [" + toString(min) + "," + toString(max) + "].");
340-
RasterData rasterData;
341-
rasterData.raster = raster;
342-
rasterData.boundary = boundary;
343-
rasterData.xSize = xSize;
344-
rasterData.ySize = ySize;
345-
myRasters.push_back(rasterData);
363+
364+
OGRSpatialReference wgs;
365+
wgs.SetWellKnownGeogCS("WGS84");
366+
367+
myRasters.push_back(RasterData{
368+
raster,
369+
boundary,
370+
xSize,
371+
ySize,
372+
OGRCreateCoordinateTransformation(&wgs, &spatialRef)
373+
});
374+
346375
return picSize;
347376
} else {
348377
return 0;
@@ -364,6 +393,9 @@ NBHeightMapper::clearData() {
364393
#ifdef HAVE_GDAL
365394
for (auto& item : myRasters) {
366395
CPLFree(item.raster);
396+
if (item.transform != nullptr) {
397+
delete item.transform;
398+
}
367399
}
368400
myRasters.clear();
369401
#endif

src/netbuild/NBHeightMapper.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ typedef __int16 int16_t;
3434
#include <utils/geom/Boundary.h>
3535
#include <utils/common/UtilExceptions.h>
3636

37+
#ifdef HAVE_GDAL
38+
#include <ogr_spatialref.h>
39+
#endif
40+
3741
#define TRIANGLE_RTREE_QUAL RTree<NBHeightMapper::Triangle*, NBHeightMapper::Triangle, float, 2, NBHeightMapper::QueryResult>
3842

3943
// ===========================================================================
@@ -128,6 +132,9 @@ class NBHeightMapper {
128132
Boundary boundary;
129133
int xSize;
130134
int ySize;
135+
#ifdef HAVE_GDAL
136+
OGRCoordinateTransformation* transform;
137+
#endif
131138
};
132139

133140
/// @brief the singleton instance

0 commit comments

Comments
 (0)