Skip to content

Commit f73364b

Browse files
committed
Add VRT support
Signed-off-by: Ryan Friedman <[email protected]>
1 parent 0196574 commit f73364b

File tree

10 files changed

+192116
-57
lines changed

10 files changed

+192116
-57
lines changed

CMakeLists.txt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,18 @@ ament_target_dependencies(${PROJECT_NAME} PUBLIC
5151
grid_map_ros
5252
)
5353

54-
add_executable(test_tif_loader
55-
src/test_tif_loader.cpp
54+
add_executable(map_publisher
55+
src/map_publisher.cpp
5656
)
5757

58-
target_link_libraries(test_tif_loader PUBLIC
58+
target_link_libraries(map_publisher PUBLIC
5959
${PROJECT_NAME}
6060
)
6161

62+
add_executable(vsicurl_local_cache
63+
src/gdal_vsicurl_local_cache.cpp
64+
)
65+
6266
# Install
6367
install(
6468
DIRECTORY include/
@@ -79,7 +83,7 @@ ament_export_dependencies(GDAL)
7983

8084
install(
8185
TARGETS
82-
test_tif_loader
86+
map_publisher vsicurl_local_cache
8387
DESTINATION lib/${PROJECT_NAME}
8488
)
8589

@@ -88,6 +92,11 @@ install(DIRECTORY
8892
DESTINATION share/${PROJECT_NAME}/
8993
)
9094

95+
install(DIRECTORY
96+
resources
97+
DESTINATION share/${PROJECT_NAME}/
98+
)
99+
91100
install(DIRECTORY
92101
rviz
93102
DESTINATION share/${PROJECT_NAME}/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This package provides a georeferenced extension to the elevation map [grid_map](
99
**Authors: Jaeyoung Lim<br />
1010
Affiliation: [ETH Zurich, Autonomous Systems Lab](https://asl.ethz.ch/)<br />**
1111
## Setup
12-
Install the dependencies. This package depends on gdal, to read georeferenced images and GeoTIFF files.
12+
Install the dependencies. This package depends on gdal, to read georeferenced images and DEM files.
1313

1414
Pull in dependencies using rosdep
1515
```

include/grid_map_geo/grid_map_geo.hpp

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,6 @@
3939
#include <grid_map_core/GridMap.hpp>
4040
#include <grid_map_core/iterators/GridMapIterator.hpp>
4141

42-
#if __APPLE__
43-
#include <cpl_string.h>
44-
#include <gdal.h>
45-
#include <gdal_priv.h>
46-
#include <ogr_p.h>
47-
#include <ogr_spatialref.h>
48-
#else
49-
#include <gdal/cpl_string.h>
50-
#include <gdal/gdal.h>
51-
#include <gdal/gdal_priv.h>
52-
#include <gdal/ogr_p.h>
53-
#include <gdal/ogr_spatialref.h>
54-
#endif
5542

5643
#include <iostream>
5744
struct Location {
@@ -116,14 +103,14 @@ class GridMapGeo {
116103
bool Load(const std::string& map_path, bool algin_terrain, const std::string color_map_path = "");
117104

118105
/**
119-
* @brief Initialize grid map from a geotiff file
106+
* @brief Initialize grid map from a GDAL dataset
120107
*
121-
* @param path Path to dsm path (Supported formats are *.tif)
108+
* @param path Path to dsm path (Supported formats are https://gdal.org/drivers/raster/index.html)
122109
* @param align_terrain
123110
* @return true Successfully loaded terrain
124111
* @return false Failed to load terrain
125112
*/
126-
bool initializeFromGeotiff(const std::string& path, bool align_terrain = true);
113+
bool initializeFromGdalDataset(const std::string& path, bool align_terrain = true);
127114

128115
/**
129116
* @brief Load a color layer from a geotiff file (orthomosaic)

launch/load_tif.launch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def generate_launch_description():
3232
tif_loader = Node(
3333
package="grid_map_geo",
3434
namespace="grid_map_geo",
35-
executable="test_tif_loader",
35+
executable="map_publisher",
3636
name="tif_loader",
3737
parameters=[
3838
{"tif_path": LaunchConfiguration("tif_path")},

launch/load_tif_launch.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<arg name="location" default="sargans"/>
44
<node pkg="tf2_ros" exec="static_transform_publisher" name="world_map" args="--frame-id world --child-frame-id map"/>
55

6-
<node pkg="grid_map_geo" exec="test_tif_loader" name="test_tif_loader" output="screen">
6+
<node pkg="grid_map_geo" exec="map_publisher" name="map_publisher" output="screen">
77
<param name="tif_path" value="$(find-pkg-share grid_map_geo)/resources/sargans.tif"/>
88
<param name="tif_color_path" value="$(find-pkg-share grid_map_geo)/resources/sargans_color.tif"/>
99
</node>

launch/load_vrt_launch.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<launch>
2+
<arg name="rviz" default="false"/>
3+
<node pkg="tf2_ros" exec="static_transform_publisher" name="world_map" args="--frame-id world --child-frame-id map"/>
4+
5+
<node pkg="grid_map_geo" exec="map_publisher" name="map_publisher" output="screen">
6+
<param name="gdal_dataset_path" value="$(find-pkg-share grid_map_geo)/resources/ap_srtm1.vrt"/>
7+
</node>
8+
9+
<group if="$(var rviz)">
10+
<node exec="rviz2" name="rviz2" pkg="rviz2" args="-d $(find-pkg-share grid_map_geo)/launch/config.rviz" />
11+
</group>
12+
</launch>

resources/ap_srtm1.vrt

Lines changed: 191983 additions & 0 deletions
Large diffs are not rendered by default.

src/gdal_vsicurl_local_cache.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2022 Jaeyoung Lim, ASL, ETH Zurich, Switzerland
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
* 2. Redistributions in binary form must reproduce the above copyright
12+
* notice, this list of conditions and the following disclaimer in
13+
* the documentation and/or other materials provided with the
14+
* distribution.
15+
* 3. Neither the name terrain-navigation nor the names of its contributors may be
16+
* used to endorse or promote products derived from this software
17+
* without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
* POSSIBILITY OF SUCH DAMAGE.
31+
*
32+
****************************************************************************/
33+
34+
/**
35+
* @brief Support caching VSICURL requests to local storage to reduce network usage
36+
*
37+
* @author Ryan Friedman <[email protected]>
38+
*/
39+
40+
41+
int main() {
42+
43+
return 0;
44+
}

src/grid_map_geo.cpp

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,41 @@
4343
#include <grid_map_core/iterators/CircleIterator.hpp>
4444
#include <grid_map_core/iterators/GridMapIterator.hpp>
4545

46+
#if __APPLE__
47+
#include <cpl_string.h>
48+
#include <gdal.h>
49+
#include <gdal_priv.h>
50+
#include <ogr_p.h>
51+
#include <ogr_spatialref.h>
52+
#else
53+
#include <gdal/cpl_string.h>
54+
#include <gdal/gdal.h>
55+
#include <gdal/gdal_priv.h>
56+
#include <gdal/ogr_p.h>
57+
#include <gdal/ogr_spatialref.h>
58+
#endif
59+
4660
GridMapGeo::GridMapGeo() {}
4761

4862
GridMapGeo::~GridMapGeo() {}
4963

5064
bool GridMapGeo::Load(const std::string &map_path, bool algin_terrain, const std::string color_map_path) {
51-
bool loaded = initializeFromGeotiff(map_path, algin_terrain);
65+
bool loaded = initializeFromGdalDataset(map_path, algin_terrain);
5266
if (!color_map_path.empty()) { // Load color layer if the color path is nonempty
5367
bool color_loaded = addColorFromGeotiff(color_map_path);
5468
}
5569
if (!loaded) return false;
5670
return true;
5771
}
5872

59-
bool GridMapGeo::initializeFromGeotiff(const std::string &path, bool align_terrain) {
73+
bool GridMapGeo::initializeFromGdalDataset(const std::string &path, bool align_terrain) {
6074
GDALAllRegister();
6175
GDALDataset *dataset = (GDALDataset *)GDALOpen(path.c_str(), GA_ReadOnly);
6276
if (!dataset) {
6377
std::cout << "Failed to open" << std::endl;
6478
return false;
6579
}
66-
std::cout << std::endl << "Loading GeoTIFF file for gridmap" << std::endl;
80+
std::cout << std::endl << "Loading GDAL Dataset for gridmap" << std::endl;
6781

6882
double originX, originY, pixelSizeX, pixelSizeY;
6983
double geoTransform[6];
@@ -80,17 +94,24 @@ bool GridMapGeo::initializeFromGeotiff(const std::string &path, bool align_terra
8094
const char *pszProjection = dataset->GetProjectionRef();
8195
std::cout << std::endl << "Wkt ProjectionRef: " << pszProjection << std::endl;
8296

97+
if (strlen(pszProjection) == 0) {
98+
// https://gdal.org/user/raster_data_model.html#coordinate-system
99+
std::cerr << std::endl << "Wkt ProjectionRef is unknown!" << std::endl;
100+
return false;
101+
}
102+
83103
// Get image metadata
84104
unsigned width = dataset->GetRasterXSize();
85105
unsigned height = dataset->GetRasterYSize();
86106
double resolution = pixelSizeX;
87-
std::cout << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
107+
std::cout << __LINE__ << "RasterX: " << width << " RasterY: " << height << " pixelSizeX: " << pixelSizeX << std::endl;
88108

89109
// pixelSizeY is negative because the origin of the image is the north-east corner and positive
90110
// Y pixel coordinates go towards the south
91111
const double lengthX = resolution * width;
92112
const double lengthY = resolution * height;
93113
grid_map::Length length(lengthX, lengthY);
114+
std::cout << __LINE__ << "GMLX: " << lengthX << " GMLY: " << lengthY << std::endl;
94115

95116
double mapcenter_e = originX + pixelSizeX * width * 0.5;
96117
double mapcenter_n = originY + pixelSizeY * height * 0.5;
@@ -115,36 +136,39 @@ bool GridMapGeo::initializeFromGeotiff(const std::string &path, bool align_terra
115136
// }
116137

117138
grid_map_.setGeometry(length, resolution, position);
118-
/// TODO: Use TF for geocoordinates
119-
grid_map_.setFrameId("map");
120-
grid_map_.add("elevation");
121-
GDALRasterBand *elevationBand = dataset->GetRasterBand(1);
122-
123-
std::vector<float> data(width * height, 0.0f);
124-
elevationBand->RasterIO(GF_Read, 0, 0, width, height, &data[0], width, height, GDT_Float32, 0, 0);
125-
126-
grid_map::Matrix &layer_elevation = grid_map_["elevation"];
127-
for (grid_map::GridMapIterator iterator(grid_map_); !iterator.isPastEnd(); ++iterator) {
128-
const grid_map::Index gridMapIndex = *iterator;
129-
// TODO: This may be wrong if the pixelSizeY > 0
130-
int x = width - 1 - gridMapIndex(0);
131-
int y = gridMapIndex(1);
132-
133-
layer_elevation(x, y) = data[gridMapIndex(0) + width * gridMapIndex(1)];
134-
}
139+
// /// TODO: Use TF for geocoordinates
140+
// grid_map_.setFrameId("map");
141+
// grid_map_.add("elevation");
142+
// const auto raster_count = dataset->GetRasterCount();
143+
// assert(raster_count == 2);
144+
// std::cout << __LINE__ << "Raster Count: " << raster_count << std::endl;
145+
// GDALRasterBand *elevationBand = dataset->GetRasterBand(1);
146+
147+
// std::vector<float> data(width * height, 0.0f);
148+
// elevationBand->RasterIO(GF_Read, 0, 0, width, height, &data[0], width, height, GDT_Float32, 0, 0);
149+
150+
// grid_map::Matrix &layer_elevation = grid_map_["elevation"];
151+
// for (grid_map::GridMapIterator iterator(grid_map_); !iterator.isPastEnd(); ++iterator) {
152+
// const grid_map::Index gridMapIndex = *iterator;
153+
// // TODO: This may be wrong if the pixelSizeY > 0
154+
// int x = width - 1 - gridMapIndex(0);
155+
// int y = gridMapIndex(1);
156+
157+
// layer_elevation(x, y) = data[gridMapIndex(0) + width * gridMapIndex(1)];
158+
// }
135159

136-
/// TODO: This is a workaround with the problem of gdal 3 not translating altitude correctly.
137-
/// This section just levels the current position to the ground
138-
double altitude{0.0};
139-
if (grid_map_.isInside(Eigen::Vector2d(0.0, 0.0))) {
140-
altitude = grid_map_.atPosition("elevation", Eigen::Vector2d(0.0, 0.0));
141-
}
160+
// /// TODO: This is a workaround with the problem of gdal 3 not translating altitude correctly.
161+
// /// This section just levels the current position to the ground
162+
// double altitude{0.0};
163+
// if (grid_map_.isInside(Eigen::Vector2d(0.0, 0.0))) {
164+
// altitude = grid_map_.atPosition("elevation", Eigen::Vector2d(0.0, 0.0));
165+
// }
142166

143167
// Eigen::Translation3d meshlab_translation(0.0, 0.0, -altitude);
144168
// Eigen::AngleAxisd meshlab_rotation(Eigen::AngleAxisd::Identity());
145169
// Eigen::Isometry3d transform = meshlab_translation * meshlab_rotation; // Apply affine transformation.
146170
// grid_map_ = grid_map_.getTransformedMap(transform, "elevation", grid_map_.getFrameId(), true);
147-
return true;
171+
return false;
148172
}
149173

150174
bool GridMapGeo::addColorFromGeotiff(const std::string &path) {
@@ -172,7 +196,7 @@ bool GridMapGeo::addColorFromGeotiff(const std::string &path) {
172196
unsigned width = dataset->GetRasterXSize();
173197
unsigned height = dataset->GetRasterYSize();
174198
double resolution = pixelSizeX;
175-
std::cout << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
199+
std::cout << __LINE__ << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
176200

177201
// pixelSizeY is negative because the origin of the image is the north-east corner and positive
178202
// Y pixel coordinates go towards the south
@@ -233,7 +257,7 @@ bool GridMapGeo::addLayerFromGeotiff(const std::string &layer_name, const std::s
233257
unsigned width = dataset->GetRasterXSize();
234258
unsigned height = dataset->GetRasterYSize();
235259
double resolution = pixelSizeX;
236-
std::cout << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
260+
std::cout << __LINE__ << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
237261

238262
// pixelSizeY is negative because the origin of the image is the north-east corner and positive
239263
// Y pixel coordinates go towards the south

src/test_tif_loader.cpp renamed to src/map_publisher.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@ class MapPublisher : public rclcpp::Node {
5252
MapPublisher() : Node("map_publisher") {
5353
original_map_pub_ = this->create_publisher<grid_map_msgs::msg::GridMap>("elevation_map", 1);
5454

55-
std::string file_path = this->declare_parameter("tif_path", ".");
55+
std::string gdal_dataset_path = this->declare_parameter("gdal_dataset_path", ".");
5656
std::string color_path = this->declare_parameter("tif_color_path", ".");
5757

58-
RCLCPP_INFO_STREAM(get_logger(), "file_path " << file_path);
59-
RCLCPP_INFO_STREAM(get_logger(), "color_path " << color_path);
58+
RCLCPP_INFO_STREAM(get_logger(), "gdal_dataset_path: '" << gdal_dataset_path << "'");
59+
RCLCPP_INFO_STREAM(get_logger(), "color_path: '" << color_path << "'");
6060

6161
map_ = std::make_shared<GridMapGeo>();
62-
map_->Load(file_path, false, color_path);
62+
map_->Load(gdal_dataset_path, false, color_path);
6363
timer_ = this->create_wall_timer(5s, std::bind(&MapPublisher::timer_callback, this));
6464
}
6565
private:

0 commit comments

Comments
 (0)