1 /******************************************************************************
2 *
3 * Project: PROJ
4 * Purpose: Test grids.hpp
5 * Author: Even Rouault <even dot rouault at spatialys dot com>
6 *
7 ******************************************************************************
8 * Copyright (c) 2020, Even Rouault <even dot rouault at spatialys dot com>
9 *
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 ****************************************************************************/
28
29 #include "gtest_include.h"
30
31 #include "grids.hpp"
32
33 #include "proj_internal.h" // M_PI
34
35 namespace {
36
37 // ---------------------------------------------------------------------------
38
39 class GridTest : public ::testing::Test {
40
DummyLogFunction(void *,int,const char *)41 static void DummyLogFunction(void *, int, const char *) {}
42
43 protected:
SetUp()44 void SetUp() override {
45 m_ctxt = proj_context_create();
46 proj_log_func(m_ctxt, nullptr, DummyLogFunction);
47 m_ctxt2 = proj_context_create();
48 proj_log_func(m_ctxt2, nullptr, DummyLogFunction);
49 }
50
TearDown()51 void TearDown() override {
52 proj_context_destroy(m_ctxt);
53 proj_context_destroy(m_ctxt2);
54 }
55
56 PJ_CONTEXT *m_ctxt = nullptr;
57 PJ_CONTEXT *m_ctxt2 = nullptr;
58 };
59
60 // ---------------------------------------------------------------------------
61
TEST_F(GridTest,VerticalShiftGridSet_null)62 TEST_F(GridTest, VerticalShiftGridSet_null) {
63 auto gridSet = NS_PROJ::VerticalShiftGridSet::open(m_ctxt, "null");
64 ASSERT_NE(gridSet, nullptr);
65 auto grid = gridSet->gridAt(0.0, 0.0);
66 ASSERT_NE(grid, nullptr);
67 EXPECT_EQ(grid->width(), 3);
68 EXPECT_EQ(grid->height(), 3);
69 EXPECT_EQ(grid->extentAndRes().west, -M_PI);
70 EXPECT_TRUE(grid->isNullGrid());
71 EXPECT_FALSE(grid->hasChanged());
72 float out = -1.0f;
73 EXPECT_TRUE(grid->valueAt(0, 0, out));
74 EXPECT_EQ(out, 0.0f);
75 EXPECT_FALSE(grid->isNodata(0.0f, 0.0));
76 gridSet->reassign_context(m_ctxt2);
77 gridSet->reopen(m_ctxt2);
78 }
79
80 // ---------------------------------------------------------------------------
81
TEST_F(GridTest,VerticalShiftGridSet_gtx)82 TEST_F(GridTest, VerticalShiftGridSet_gtx) {
83 ASSERT_EQ(NS_PROJ::VerticalShiftGridSet::open(m_ctxt, "foobar"), nullptr);
84 auto gridSet =
85 NS_PROJ::VerticalShiftGridSet::open(m_ctxt, "tests/test_nodata.gtx");
86 ASSERT_NE(gridSet, nullptr);
87 ASSERT_EQ(gridSet->gridAt(-100, -100), nullptr);
88 auto grid = gridSet->gridAt(4.15 / 180 * M_PI, 52.15 / 180 * M_PI);
89 ASSERT_NE(grid, nullptr);
90 EXPECT_TRUE(grid->isNodata(-88.8888f, 1.0));
91 gridSet->reassign_context(m_ctxt2);
92 gridSet->reopen(m_ctxt2);
93 grid = gridSet->gridAt(4.15 / 180 * M_PI, 52.15 / 180 * M_PI);
94 EXPECT_NE(grid, nullptr);
95 }
96
97 // ---------------------------------------------------------------------------
98
TEST_F(GridTest,HorizontalShiftGridSet_null)99 TEST_F(GridTest, HorizontalShiftGridSet_null) {
100 auto gridSet = NS_PROJ::HorizontalShiftGridSet::open(m_ctxt, "null");
101 ASSERT_NE(gridSet, nullptr);
102 auto grid = gridSet->gridAt(0.0, 0.0);
103 ASSERT_NE(grid, nullptr);
104 EXPECT_EQ(grid->width(), 3);
105 EXPECT_EQ(grid->height(), 3);
106 EXPECT_EQ(grid->extentAndRes().west, -M_PI);
107 EXPECT_TRUE(grid->isNullGrid());
108 EXPECT_FALSE(grid->hasChanged());
109 float out1 = -1.0f;
110 float out2 = -1.0f;
111 EXPECT_TRUE(grid->valueAt(0, 0, false, out1, out2));
112 EXPECT_EQ(out1, 0.0f);
113 EXPECT_EQ(out2, 0.0f);
114 gridSet->reassign_context(m_ctxt2);
115 gridSet->reopen(m_ctxt2);
116 }
117
118 // ---------------------------------------------------------------------------
119
TEST_F(GridTest,HorizontalShiftGridSet_gtiff)120 TEST_F(GridTest, HorizontalShiftGridSet_gtiff) {
121 auto gridSet =
122 NS_PROJ::HorizontalShiftGridSet::open(m_ctxt, "tests/test_hgrid.tif");
123 ASSERT_NE(gridSet, nullptr);
124 EXPECT_EQ(gridSet->format(), "gtiff");
125 EXPECT_TRUE(gridSet->name().find("tests/test_hgrid.tif") !=
126 std::string::npos)
127 << gridSet->name();
128 EXPECT_EQ(gridSet->grids().size(), 1U);
129 ASSERT_EQ(gridSet->gridAt(-100, -100), nullptr);
130 auto grid = gridSet->gridAt(5.5 / 180 * M_PI, 53.5 / 180 * M_PI);
131 ASSERT_NE(grid, nullptr);
132 EXPECT_EQ(grid->width(), 4);
133 EXPECT_EQ(grid->height(), 4);
134 EXPECT_EQ(grid->extentAndRes().west, 4.0 / 180 * M_PI);
135 EXPECT_FALSE(grid->isNullGrid());
136 EXPECT_FALSE(grid->hasChanged());
137 float out1 = -1.0f;
138 float out2 = -1.0f;
139 EXPECT_TRUE(grid->valueAt(0, 3, false, out1, out2));
140 EXPECT_EQ(out1, static_cast<float>(14400.0 / 3600. / 180 * M_PI));
141 EXPECT_EQ(out2, static_cast<float>(900.0 / 3600. / 180 * M_PI));
142 gridSet->reassign_context(m_ctxt2);
143 gridSet->reopen(m_ctxt2);
144 grid = gridSet->gridAt(5.5 / 180 * M_PI, 53.5 / 180 * M_PI);
145 EXPECT_NE(grid, nullptr);
146 }
147
148 // ---------------------------------------------------------------------------
149
TEST_F(GridTest,GenericShiftGridSet_null)150 TEST_F(GridTest, GenericShiftGridSet_null) {
151 auto gridSet = NS_PROJ::GenericShiftGridSet::open(m_ctxt, "null");
152 ASSERT_NE(gridSet, nullptr);
153 auto grid = gridSet->gridAt(0.0, 0.0);
154 ASSERT_NE(grid, nullptr);
155 EXPECT_EQ(grid->width(), 3);
156 EXPECT_EQ(grid->height(), 3);
157 EXPECT_EQ(grid->extentAndRes().west, -M_PI);
158 EXPECT_TRUE(grid->isNullGrid());
159 EXPECT_FALSE(grid->hasChanged());
160 float out = -1.0f;
161 EXPECT_TRUE(grid->valueAt(0, 0, 0, out));
162 EXPECT_EQ(out, 0.0f);
163 EXPECT_EQ(grid->unit(0), "");
164 EXPECT_EQ(grid->description(0), "");
165 EXPECT_EQ(grid->metadataItem("foo"), "");
166 EXPECT_EQ(grid->samplesPerPixel(), 0);
167 gridSet->reassign_context(m_ctxt2);
168 gridSet->reopen(m_ctxt2);
169 }
170
171 // ---------------------------------------------------------------------------
172
TEST_F(GridTest,GenericShiftGridSet_gtiff)173 TEST_F(GridTest, GenericShiftGridSet_gtiff) {
174 ASSERT_EQ(NS_PROJ::GenericShiftGridSet::open(m_ctxt, "foobar"), nullptr);
175 auto gridSet = NS_PROJ::GenericShiftGridSet::open(
176 m_ctxt, "tests/nkgrf03vel_realigned_extract.tif");
177 ASSERT_NE(gridSet, nullptr);
178 ASSERT_EQ(gridSet->gridAt(-100, -100), nullptr);
179 auto grid = gridSet->gridAt(21.3333333 / 180 * M_PI, 63.0 / 180 * M_PI);
180 ASSERT_NE(grid, nullptr);
181 EXPECT_EQ(grid->width(), 5);
182 EXPECT_EQ(grid->height(), 5);
183 EXPECT_EQ(grid->extentAndRes().isGeographic, true);
184 EXPECT_EQ(grid->extentAndRes().west, 21.0 / 180 * M_PI);
185 EXPECT_FALSE(grid->isNullGrid());
186 EXPECT_FALSE(grid->hasChanged());
187 float out = -1.0f;
188 EXPECT_FALSE(grid->valueAt(0, 0, grid->samplesPerPixel(), out));
189 EXPECT_EQ(grid->metadataItem("area_of_use"), "Nordic and Baltic countries");
190 EXPECT_EQ(grid->metadataItem("non_existing"), std::string());
191 EXPECT_EQ(grid->metadataItem("non_existing", 1), std::string());
192 EXPECT_EQ(grid->metadataItem("non_existing", 10), std::string());
193 gridSet->reassign_context(m_ctxt2);
194 gridSet->reopen(m_ctxt2);
195 grid = gridSet->gridAt(21.3333333 / 180 * M_PI, 63.0 / 180 * M_PI);
196 EXPECT_NE(grid, nullptr);
197 }
198
199 // ---------------------------------------------------------------------------
200
TEST_F(GridTest,GenericShiftGridSet_gtiff_with_subgrid)201 TEST_F(GridTest, GenericShiftGridSet_gtiff_with_subgrid) {
202 auto gridSet = NS_PROJ::GenericShiftGridSet::open(
203 m_ctxt, "tests/test_hgrid_with_subgrid.tif");
204 ASSERT_NE(gridSet, nullptr);
205 ASSERT_EQ(gridSet->gridAt(-100, -100), nullptr);
206 auto grid =
207 gridSet->gridAt(-115.5416667 / 180 * M_PI, 51.1666667 / 180 * M_PI);
208 ASSERT_NE(grid, nullptr);
209 EXPECT_EQ(grid->width(), 11);
210 EXPECT_EQ(grid->height(), 21);
211 EXPECT_EQ(grid->metadataItem("grid_name"), "ALbanff");
212 }
213
214 // ---------------------------------------------------------------------------
215
TEST_F(GridTest,GenericShiftGridSet_gtiff_with_two_level_of_subgrids_no_grid_name)216 TEST_F(GridTest,
217 GenericShiftGridSet_gtiff_with_two_level_of_subgrids_no_grid_name) {
218 auto gridSet = NS_PROJ::GenericShiftGridSet::open(
219 m_ctxt, "tests/test_hgrid_with_two_level_of_subgrids_no_grid_name.tif");
220 ASSERT_NE(gridSet, nullptr);
221 ASSERT_EQ(gridSet->gridAt(-100, -100), nullptr);
222 auto grid = gridSet->gridAt(-45.5 / 180 * M_PI, 22.5 / 180 * M_PI);
223 ASSERT_NE(grid, nullptr);
224 EXPECT_EQ(grid->width(), 8);
225 EXPECT_EQ(grid->height(), 8);
226 }
227
228 // ---------------------------------------------------------------------------
229
TEST_F(GridTest,GenericShiftGridSet_gtiff_projected)230 TEST_F(GridTest, GenericShiftGridSet_gtiff_projected) {
231 auto gridSet = NS_PROJ::GenericShiftGridSet::open(
232 m_ctxt, "tests/test_3d_grid_projected.tif");
233 ASSERT_NE(gridSet, nullptr);
234 ASSERT_EQ(gridSet->gridAt(-1000, -1000), nullptr);
235 auto grid = gridSet->gridAt(1500300.0, 5400300.0);
236 ASSERT_NE(grid, nullptr);
237 EXPECT_EQ(grid->width(), 2);
238 EXPECT_EQ(grid->height(), 2);
239 EXPECT_EQ(grid->extentAndRes().isGeographic, false);
240 EXPECT_EQ(grid->extentAndRes().west, 1500000.0);
241 EXPECT_EQ(grid->extentAndRes().east, 1501000.0);
242 EXPECT_EQ(grid->extentAndRes().south, 5400000.0);
243 EXPECT_EQ(grid->extentAndRes().north, 5401000.0);
244 EXPECT_EQ(grid->extentAndRes().resX, 1000);
245 EXPECT_EQ(grid->extentAndRes().resY, 1000);
246 }
247
248 } // namespace
249