diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f11b14151..3af56b8440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * FIXED: update CircleCI runners to Ubuntu 24.04 [#5002](https://github.com/valhalla/valhalla/pull/5002) * FIXED: Fixed a typo in the (previously undocumented) matrix-APIs responses `algorithm` field: `timedistancbssematrix` is now `timedistancebssmatrix` [#5000](https://github.com/valhalla/valhalla/pull/5000). * FIXED: More trivial cases in `CostMatrix` [#5001](https://github.com/valhalla/valhalla/pull/5001) + * FIXED: Make isochrone geotiff serialization use "north up" geotransform [#5019](https://github.com/valhalla/valhalla/pull/5019) * **Enhancement** * ADDED: Consider smoothness in all profiles that use surface [#4949](https://github.com/valhalla/valhalla/pull/4949) * ADDED: `admin_crossings` request parameter for `/route` [#4941](https://github.com/valhalla/valhalla/pull/4941) diff --git a/src/tyr/isochrone_serializer.cc b/src/tyr/isochrone_serializer.cc index 22943370e4..bf585bf67b 100644 --- a/src/tyr/isochrone_serializer.cc +++ b/src/tyr/isochrone_serializer.cc @@ -197,10 +197,9 @@ std::string serializeGeoTIFF(Api& request, const std::shared_ptrTileBounds(isogrid->TileId(box[0], box[1])).minx(), // minx isogrid->TileSize(), 0, - isogrid->TileBounds(isogrid->TileId(box[0], box[1])).miny(), // miny + isogrid->TileBounds(isogrid->TileId(box[0], box[3])).maxy(), // maxy 0, - isogrid->TileSize()}; - + -isogrid->TileSize()}; geotiff_dataset->SetGeoTransform(geo_transform); geotiff_dataset->SetSpatialRef(const_cast(&spatial_ref)); @@ -214,10 +213,11 @@ std::string serializeGeoTIFF(Api& request, const std::shared_ptrTileId(j + box[0], i + box[1]); - data[i * ext_x + j] = + data[(ext_y - 1 - i) * ext_x + j] = static_cast(isogrid->DataAt(tileid, metric_idx) * scale_factor); } } + auto band = geotiff_dataset->GetRasterBand(nbands == 2 ? (metric_idx + 1) : 1); band->SetNoDataValue(std::numeric_limits::max()); band->SetDescription(metric_idx == 0 ? "Time (seconds)" : "Distance (10m)"); diff --git a/test/isochrone.cc b/test/isochrone.cc index 667402fb6b..788596740f 100644 --- a/test/isochrone.cc +++ b/test/isochrone.cc @@ -495,6 +495,31 @@ TEST(Isochrones, test_geotiff_output_time_distance) { } VSIFCloseL(handle); } +TEST(Isochrones, test_geotiff_vertical_orientation) { + loki_worker_t loki_worker(cfg); + thor_worker_t thor_worker(cfg); + + const auto request = + R"({"costing":"auto","locations":[{"lon":5.042799,"lat":52.093199}],"contours":[{"distance":1}], "format": "geotiff"})"; + Api request_pbf; + ParseApi(request, Options::isochrone, request_pbf); + loki_worker.isochrones(request_pbf); + std::string geotiff = thor_worker.isochrones(request_pbf); + + std::string name = "/vsimem/test_isogrid_geotiff_d.tif"; + unsigned char buffer[geotiff.length()]; + std::copy(geotiff.cbegin(), geotiff.cend(), buffer); + auto handle = VSIFileFromMemBuffer(name.c_str(), buffer, static_cast(geotiff.size()), 0); + auto geotiff_dataset = GDALDataset::FromHandle(GDALOpen(name.c_str(), GA_ReadOnly)); + int y = geotiff_dataset->GetRasterYSize(); + double geoTransform[6]; + geotiff_dataset->GetGeoTransform(geoTransform); + double topY = geoTransform[3] + 0 * geoTransform[4] + 0 * geoTransform[5]; + double bottomY = geoTransform[3] + 0 * geoTransform[4] + y * geoTransform[5]; + ASSERT_TRUE(topY > bottomY); + + VSIFCloseL(handle); +} #endif } // namespace