aboutsummaryrefslogtreecommitdiff
path: root/test/unit/test_c_api.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@mines-paris.org>2018-11-15 10:12:17 +0100
committerGitHub <noreply@github.com>2018-11-15 10:12:17 +0100
commit4ad1477c24c3da4be6c7962606e6f9d47336b6a3 (patch)
treeeb4ca374b50ab3c1183a25ac264245c7b4fd681b /test/unit/test_c_api.cpp
parent73865a4df1a7d4c37052647f0458567751735f00 (diff)
parentd928db15d53805d9b728b440079756081961c536 (diff)
downloadPROJ-4ad1477c24c3da4be6c7962606e6f9d47336b6a3.tar.gz
PROJ-4ad1477c24c3da4be6c7962606e6f9d47336b6a3.zip
Merge pull request #1175 from rouault/iso19111_for_merge
Implement RFC 2: Initial integration of "GDAL SRS barn" work
Diffstat (limited to 'test/unit/test_c_api.cpp')
-rw-r--r--test/unit/test_c_api.cpp1925
1 files changed, 1925 insertions, 0 deletions
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
new file mode 100644
index 00000000..207a8cd1
--- /dev/null
+++ b/test/unit/test_c_api.cpp
@@ -0,0 +1,1925 @@
+/******************************************************************************
+ *
+ * Project: PROJ
+ * Purpose: Test ISO19111:2018 implementation
+ * Author: Even Rouault <even dot rouault at spatialys dot com>
+ *
+ ******************************************************************************
+ * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ ****************************************************************************/
+
+#include "gtest_include.h"
+
+#include "proj.h"
+
+#include "proj/common.hpp"
+#include "proj/coordinateoperation.hpp"
+#include "proj/coordinatesystem.hpp"
+#include "proj/crs.hpp"
+#include "proj/datum.hpp"
+#include "proj/io.hpp"
+#include "proj/metadata.hpp"
+#include "proj/util.hpp"
+
+using namespace osgeo::proj::common;
+using namespace osgeo::proj::crs;
+using namespace osgeo::proj::cs;
+using namespace osgeo::proj::datum;
+using namespace osgeo::proj::io;
+using namespace osgeo::proj::metadata;
+using namespace osgeo::proj::operation;
+using namespace osgeo::proj::util;
+
+namespace {
+
+class CApi : public ::testing::Test {
+
+ static void DummyLogFunction(void *, int, const char *) {}
+
+ protected:
+ void SetUp() override {
+ m_ctxt = proj_context_create();
+ proj_log_func(m_ctxt, nullptr, DummyLogFunction);
+ }
+
+ void TearDown() override { proj_context_destroy(m_ctxt); }
+
+ static BoundCRSNNPtr createBoundCRS() {
+ return BoundCRS::create(
+ GeographicCRS::EPSG_4807, GeographicCRS::EPSG_4326,
+ Transformation::create(PropertyMap(), GeographicCRS::EPSG_4807,
+ GeographicCRS::EPSG_4326, nullptr,
+ PropertyMap(), {}, {}, {}));
+ }
+
+ static ProjectedCRSNNPtr createProjectedCRS() {
+ PropertyMap propertiesCRS;
+ propertiesCRS.set(Identifier::CODESPACE_KEY, "EPSG")
+ .set(Identifier::CODE_KEY, 32631)
+ .set(IdentifiedObject::NAME_KEY, "WGS 84 / UTM zone 31N");
+ return ProjectedCRS::create(
+ propertiesCRS, GeographicCRS::EPSG_4326,
+ Conversion::createUTM(PropertyMap(), 31, true),
+ CartesianCS::createEastingNorthing(UnitOfMeasure::METRE));
+ }
+
+ static VerticalCRSNNPtr createVerticalCRS() {
+ PropertyMap propertiesVDatum;
+ propertiesVDatum.set(Identifier::CODESPACE_KEY, "EPSG")
+ .set(Identifier::CODE_KEY, 5101)
+ .set(IdentifiedObject::NAME_KEY, "Ordnance Datum Newlyn");
+ auto vdatum = VerticalReferenceFrame::create(propertiesVDatum);
+ PropertyMap propertiesCRS;
+ propertiesCRS.set(Identifier::CODESPACE_KEY, "EPSG")
+ .set(Identifier::CODE_KEY, 5701)
+ .set(IdentifiedObject::NAME_KEY, "ODN height");
+ return VerticalCRS::create(
+ propertiesCRS, vdatum,
+ VerticalCS::createGravityRelatedHeight(UnitOfMeasure::METRE));
+ }
+
+ static CompoundCRSNNPtr createCompoundCRS() {
+ PropertyMap properties;
+ properties.set(Identifier::CODESPACE_KEY, "codespace")
+ .set(Identifier::CODE_KEY, "code")
+ .set(IdentifiedObject::NAME_KEY, "horizontal + vertical");
+ return CompoundCRS::create(
+ properties,
+ std::vector<CRSNNPtr>{createProjectedCRS(), createVerticalCRS()});
+ }
+
+ PJ_CONTEXT *m_ctxt = nullptr;
+
+ struct ObjectKeeper {
+ PJ_OBJ *m_obj = nullptr;
+ explicit ObjectKeeper(PJ_OBJ *obj) : m_obj(obj) {}
+ ~ObjectKeeper() { proj_obj_unref(m_obj); }
+
+ ObjectKeeper(const ObjectKeeper &) = delete;
+ ObjectKeeper &operator=(const ObjectKeeper &) = delete;
+ };
+
+ struct ContextKeeper {
+ PJ_OPERATION_FACTORY_CONTEXT *m_op_ctxt = nullptr;
+ explicit ContextKeeper(PJ_OPERATION_FACTORY_CONTEXT *op_ctxt)
+ : m_op_ctxt(op_ctxt) {}
+ ~ContextKeeper() { proj_operation_factory_context_unref(m_op_ctxt); }
+
+ ContextKeeper(const ContextKeeper &) = delete;
+ ContextKeeper &operator=(const ContextKeeper &) = delete;
+ };
+
+ struct ObjListKeeper {
+ PJ_OBJ_LIST *m_res = nullptr;
+ explicit ObjListKeeper(PJ_OBJ_LIST *res) : m_res(res) {}
+ ~ObjListKeeper() { proj_obj_list_unref(m_res); }
+
+ ObjListKeeper(const ObjListKeeper &) = delete;
+ ObjListKeeper &operator=(const ObjListKeeper &) = delete;
+ };
+};
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_from_user_input) {
+ proj_obj_unref(nullptr);
+ EXPECT_EQ(proj_obj_create_from_user_input(m_ctxt, "invalid", nullptr),
+ nullptr);
+ {
+ auto obj = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+ }
+ {
+ auto obj =
+ proj_obj_create_from_user_input(m_ctxt, "EPSG:4326", nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_from_wkt) {
+ proj_obj_unref(nullptr);
+ EXPECT_EQ(proj_obj_create_from_wkt(m_ctxt, "invalid", nullptr), nullptr);
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_from_proj_string) {
+ proj_obj_unref(nullptr);
+ EXPECT_EQ(proj_obj_create_from_proj_string(m_ctxt, "invalid", nullptr),
+ nullptr);
+ auto obj =
+ proj_obj_create_from_proj_string(m_ctxt, "+proj=longlat", nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_NE(obj, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_as_wkt) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEOGCRS[") == 0) << wkt;
+ }
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018_SIMPLIFIED, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEOGCRS[") == 0) << wkt;
+ EXPECT_TRUE(std::string(wkt).find("ANGULARUNIT[") == std::string::npos)
+ << wkt;
+ }
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2015, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEODCRS[") == 0) << wkt;
+ }
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2015_SIMPLIFIED, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEODCRS[") == 0) << wkt;
+ EXPECT_TRUE(std::string(wkt).find("ANGULARUNIT[") == std::string::npos)
+ << wkt;
+ }
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEOGCS[\"WGS 84\"") == 0) << wkt;
+ }
+
+ {
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_ESRI, nullptr);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("GEOGCS[\"GCS_WGS_1984\"") == 0)
+ << wkt;
+ }
+
+ // MULTILINE=NO
+ {
+ const char *const options[] = {"MULTILINE=NO", nullptr};
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("\n") == std::string::npos) << wkt;
+ }
+
+ // INDENTATION_WIDTH=2
+ {
+ const char *const options[] = {"INDENTATION_WIDTH=2", nullptr};
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("\n DATUM") != std::string::npos)
+ << wkt;
+ }
+
+ // OUTPUT_AXIS=NO
+ {
+ const char *const options[] = {"OUTPUT_AXIS=NO", nullptr};
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, options);
+ ASSERT_NE(wkt, nullptr);
+ EXPECT_TRUE(std::string(wkt).find("AXIS") == std::string::npos) << wkt;
+ }
+
+ // unsupported option
+ {
+ const char *const options[] = {"unsupported=yes", nullptr};
+ auto wkt = proj_obj_as_wkt(obj, PJ_WKT2_2018, options);
+ EXPECT_EQ(wkt, nullptr);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_as_wkt_incompatible_WKT1) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ createBoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto wkt1_GDAL = proj_obj_as_wkt(obj, PJ_WKT1_GDAL, nullptr);
+ ASSERT_EQ(wkt1_GDAL, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_as_proj_string) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ {
+ auto proj_5 = proj_obj_as_proj_string(obj, PJ_PROJ_5, nullptr);
+ ASSERT_NE(proj_5, nullptr);
+ EXPECT_EQ(std::string(proj_5), "+proj=pipeline +step +proj=longlat "
+ "+ellps=WGS84 +step +proj=unitconvert "
+ "+xy_in=rad +xy_out=deg +step "
+ "+proj=axisswap +order=2,1");
+ }
+ {
+ auto proj_4 = proj_obj_as_proj_string(obj, PJ_PROJ_4, nullptr);
+ ASSERT_NE(proj_4, nullptr);
+ EXPECT_EQ(std::string(proj_4), "+proj=longlat +datum=WGS84");
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_as_proj_string_incompatible_WKT1) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ createBoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto str = proj_obj_as_proj_string(obj, PJ_PROJ_5, nullptr);
+ ASSERT_EQ(str, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_as_proj_string_etmerc_option) {
+ auto obj = proj_obj_create_from_proj_string(m_ctxt, "+proj=tmerc", nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ const char *options[] = {"USE_ETMERC=YES", nullptr};
+ auto str = proj_obj_as_proj_string(obj, PJ_PROJ_4, options);
+ ASSERT_NE(str, nullptr);
+ EXPECT_EQ(str, std::string("+proj=etmerc +lat_0=0 +lon_0=0 +k_0=1 +x_0=0 "
+ "+y_0=0 +datum=WGS84"));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84) {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "3844", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ObjectKeeper keeper(crs);
+ ASSERT_NE(crs, nullptr);
+
+ auto res = proj_obj_crs_create_bound_crs_to_WGS84(crs);
+ ObjectKeeper keeper_res(res);
+ ASSERT_NE(res, nullptr);
+
+ auto proj_4 = proj_obj_as_proj_string(res, PJ_PROJ_4, nullptr);
+ ASSERT_NE(proj_4, nullptr);
+ EXPECT_EQ(std::string(proj_4),
+ "+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 "
+ "+y_0=500000 +ellps=krass "
+ "+towgs84=2.329,-147.042,-92.08,-0.309,0.325,0.497,5.69");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_crs_create_bound_crs_to_WGS84_on_invalid_type) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createProjectedCRS()
+ ->derivingConversion()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto res = proj_obj_crs_create_bound_crs_to_WGS84(obj);
+ ASSERT_EQ(res, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_name) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ auto name = proj_obj_get_name(obj);
+ ASSERT_TRUE(name != nullptr);
+ EXPECT_EQ(name, std::string("WGS 84"));
+ EXPECT_EQ(name, proj_obj_get_name(obj));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_id_auth_name) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ auto auth = proj_obj_get_id_auth_name(obj, 0);
+ ASSERT_TRUE(auth != nullptr);
+ EXPECT_EQ(auth, std::string("EPSG"));
+ EXPECT_EQ(auth, proj_obj_get_id_auth_name(obj, 0));
+ EXPECT_EQ(proj_obj_get_id_auth_name(obj, -1), nullptr);
+ EXPECT_EQ(proj_obj_get_id_auth_name(obj, 1), nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_id_code) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ auto code = proj_obj_get_id_code(obj, 0);
+ ASSERT_TRUE(code != nullptr);
+ EXPECT_EQ(code, std::string("4326"));
+ EXPECT_EQ(code, proj_obj_get_id_code(obj, 0));
+ EXPECT_EQ(proj_obj_get_id_code(obj, -1), nullptr);
+ EXPECT_EQ(proj_obj_get_id_code(obj, 1), nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_type) {
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_GEOGRAPHIC_2D_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4979->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_GEOGRAPHIC_3D_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4978->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_GEOCENTRIC_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, GeographicCRS::EPSG_4326->datum()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_GEODETIC_REFERENCE_FRAME);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, GeographicCRS::EPSG_4326->ellipsoid()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_ELLIPSOID);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createProjectedCRS()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_PROJECTED_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createVerticalCRS()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_VERTICAL_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createVerticalCRS()
+ ->datum()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_VERTICAL_REFERENCE_FRAME);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createProjectedCRS()
+ ->derivingConversion()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_CONVERSION);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ createBoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_BOUND_CRS);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createBoundCRS()
+ ->transformation()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_obj_get_type(obj), PJ_OBJ_TYPE_TRANSFORMATION);
+ }
+ {
+ auto obj = proj_obj_create_from_wkt(m_ctxt, "AUTHORITY[\"EPSG\", 4326]",
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_EQ(obj, nullptr);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_from_database) {
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "-1", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_EQ(crs, nullptr);
+ }
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_TRUE(proj_obj_is_crs(crs));
+ EXPECT_FALSE(proj_obj_is_deprecated(crs));
+ EXPECT_EQ(proj_obj_get_type(crs), PJ_OBJ_TYPE_GEOGRAPHIC_2D_CRS);
+ }
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "6871", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_TRUE(proj_obj_is_crs(crs));
+ EXPECT_EQ(proj_obj_get_type(crs), PJ_OBJ_TYPE_COMPOUND_CRS);
+ }
+ {
+ auto ellipsoid = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "7030", PJ_OBJ_CATEGORY_ELLIPSOID, false, nullptr);
+ ASSERT_NE(ellipsoid, nullptr);
+ ObjectKeeper keeper(ellipsoid);
+ EXPECT_EQ(proj_obj_get_type(ellipsoid), PJ_OBJ_TYPE_ELLIPSOID);
+ }
+ {
+ auto datum = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "6326", PJ_OBJ_CATEGORY_DATUM, false, nullptr);
+ ASSERT_NE(datum, nullptr);
+ ObjectKeeper keeper(datum);
+ EXPECT_EQ(proj_obj_get_type(datum),
+ PJ_OBJ_TYPE_GEODETIC_REFERENCE_FRAME);
+ }
+ {
+ auto op = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "16031", PJ_OBJ_CATEGORY_COORDINATE_OPERATION,
+ false, nullptr);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper(op);
+ EXPECT_EQ(proj_obj_get_type(op), PJ_OBJ_TYPE_CONVERSION);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_crs) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()
+ ->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get())
+ .c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_TRUE(proj_obj_is_crs(crs));
+
+ auto geodCRS = proj_obj_crs_get_geodetic_crs(crs);
+ ASSERT_NE(geodCRS, nullptr);
+ ObjectKeeper keeper_geogCRS(geodCRS);
+ EXPECT_TRUE(proj_obj_is_crs(geodCRS));
+ auto geogCRS_name = proj_obj_get_name(geodCRS);
+ ASSERT_TRUE(geogCRS_name != nullptr);
+ EXPECT_EQ(geogCRS_name, std::string("WGS 84"));
+
+ auto datum = proj_obj_crs_get_horizontal_datum(crs);
+ ASSERT_NE(datum, nullptr);
+ ObjectKeeper keeper_datum(datum);
+ auto datum_name = proj_obj_get_name(datum);
+ ASSERT_TRUE(datum_name != nullptr);
+ EXPECT_EQ(datum_name, std::string("World Geodetic System 1984"));
+
+ auto ellipsoid = proj_obj_get_ellipsoid(crs);
+ ASSERT_NE(ellipsoid, nullptr);
+ ObjectKeeper keeper_ellipsoid(ellipsoid);
+ auto ellipsoid_name = proj_obj_get_name(ellipsoid);
+ ASSERT_TRUE(ellipsoid_name != nullptr);
+ EXPECT_EQ(ellipsoid_name, std::string("WGS 84"));
+
+ auto ellipsoid_from_datum = proj_obj_get_ellipsoid(datum);
+ ASSERT_NE(ellipsoid_from_datum, nullptr);
+ ObjectKeeper keeper_ellipsoid_from_datum(ellipsoid_from_datum);
+
+ EXPECT_EQ(proj_obj_get_ellipsoid(ellipsoid), nullptr);
+ EXPECT_FALSE(proj_obj_is_crs(ellipsoid));
+
+ double a;
+ double b;
+ int b_is_computed;
+ double rf;
+ EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(ellipsoid, nullptr, nullptr,
+ nullptr, nullptr));
+ EXPECT_TRUE(proj_obj_ellipsoid_get_parameters(ellipsoid, &a, &b,
+ &b_is_computed, &rf));
+ EXPECT_FALSE(
+ proj_obj_ellipsoid_get_parameters(crs, &a, &b, &b_is_computed, &rf));
+ EXPECT_EQ(a, 6378137);
+ EXPECT_NEAR(b, 6356752.31424518, 1e-9);
+ EXPECT_EQ(b_is_computed, 1);
+ EXPECT_EQ(rf, 298.257223563);
+ auto id = proj_obj_get_id_code(ellipsoid, 0);
+ ASSERT_TRUE(id != nullptr);
+ EXPECT_EQ(id, std::string("7030"));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_prime_meridian) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()
+ ->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get())
+ .c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ auto pm = proj_obj_get_prime_meridian(crs);
+ ASSERT_NE(pm, nullptr);
+ ObjectKeeper keeper_pm(pm);
+ auto pm_name = proj_obj_get_name(pm);
+ ASSERT_TRUE(pm_name != nullptr);
+ EXPECT_EQ(pm_name, std::string("Greenwich"));
+
+ EXPECT_EQ(proj_obj_get_prime_meridian(pm), nullptr);
+
+ EXPECT_TRUE(
+ proj_obj_prime_meridian_get_parameters(pm, nullptr, nullptr, nullptr));
+ double longitude = -1;
+ double longitude_unit = 0;
+ const char *longitude_unit_name = nullptr;
+ EXPECT_TRUE(proj_obj_prime_meridian_get_parameters(
+ pm, &longitude, &longitude_unit, &longitude_unit_name));
+ EXPECT_EQ(longitude, 0);
+ EXPECT_NEAR(longitude_unit, UnitOfMeasure::DEGREE.conversionToSI(), 1e-10);
+ ASSERT_TRUE(longitude_unit_name != nullptr);
+ EXPECT_EQ(longitude_unit_name, std::string("degree"));
+
+ auto datum = proj_obj_crs_get_horizontal_datum(crs);
+ ASSERT_NE(datum, nullptr);
+ ObjectKeeper keeper_datum(datum);
+ auto pm_from_datum = proj_obj_get_prime_meridian(datum);
+ ASSERT_NE(pm_from_datum, nullptr);
+ ObjectKeeper keeper_pm_from_datum(pm_from_datum);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_crs_compound) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createCompoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_EQ(proj_obj_get_type(crs), PJ_OBJ_TYPE_COMPOUND_CRS);
+
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(crs, -1), nullptr);
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(crs, 2), nullptr);
+
+ auto subcrs_horiz = proj_obj_crs_get_sub_crs(crs, 0);
+ ASSERT_NE(subcrs_horiz, nullptr);
+ ObjectKeeper keeper_subcrs_horiz(subcrs_horiz);
+ EXPECT_EQ(proj_obj_get_type(subcrs_horiz), PJ_OBJ_TYPE_PROJECTED_CRS);
+ EXPECT_EQ(proj_obj_crs_get_sub_crs(subcrs_horiz, 0), nullptr);
+
+ auto subcrs_vertical = proj_obj_crs_get_sub_crs(crs, 1);
+ ASSERT_NE(subcrs_vertical, nullptr);
+ ObjectKeeper keeper_subcrs_vertical(subcrs_vertical);
+ EXPECT_EQ(proj_obj_get_type(subcrs_vertical), PJ_OBJ_TYPE_VERTICAL_CRS);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_source_target_crs_bound_crs) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createBoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ auto sourceCRS = proj_obj_get_source_crs(crs);
+ ASSERT_NE(sourceCRS, nullptr);
+ ObjectKeeper keeper_sourceCRS(sourceCRS);
+ EXPECT_EQ(std::string(proj_obj_get_name(sourceCRS)), "NTF (Paris)");
+
+ auto targetCRS = proj_obj_get_target_crs(crs);
+ ASSERT_NE(targetCRS, nullptr);
+ ObjectKeeper keeper_targetCRS(targetCRS);
+ EXPECT_EQ(std::string(proj_obj_get_name(targetCRS)), "WGS 84");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_source_target_crs_transformation) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, createBoundCRS()
+ ->transformation()
+ ->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ASSERT_NE(obj, nullptr);
+ ObjectKeeper keeper(obj);
+
+ auto sourceCRS = proj_obj_get_source_crs(obj);
+ ASSERT_NE(sourceCRS, nullptr);
+ ObjectKeeper keeper_sourceCRS(sourceCRS);
+ EXPECT_EQ(std::string(proj_obj_get_name(sourceCRS)), "NTF (Paris)");
+
+ auto targetCRS = proj_obj_get_target_crs(obj);
+ ASSERT_NE(targetCRS, nullptr);
+ ObjectKeeper keeper_targetCRS(targetCRS);
+ EXPECT_EQ(std::string(proj_obj_get_name(targetCRS)), "WGS 84");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_source_target_crs_conversion_without_crs) {
+ auto obj = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "16031", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, false,
+ nullptr);
+ ASSERT_NE(obj, nullptr);
+ ObjectKeeper keeper(obj);
+
+ auto sourceCRS = proj_obj_get_source_crs(obj);
+ ASSERT_EQ(sourceCRS, nullptr);
+
+ auto targetCRS = proj_obj_get_target_crs(obj);
+ ASSERT_EQ(targetCRS, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_source_target_crs_invalid_object) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt, "ELLIPSOID[\"WGS 84\",6378137,298.257223563]", nullptr);
+ ASSERT_NE(obj, nullptr);
+ ObjectKeeper keeper(obj);
+
+ auto sourceCRS = proj_obj_get_source_crs(obj);
+ ASSERT_EQ(sourceCRS, nullptr);
+
+ auto targetCRS = proj_obj_get_target_crs(obj);
+ ASSERT_EQ(targetCRS, nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+struct ListFreer {
+ PROJ_STRING_LIST list;
+ ListFreer(PROJ_STRING_LIST ptrIn) : list(ptrIn) {}
+ ~ListFreer() { proj_free_string_list(list); }
+ ListFreer(const ListFreer &) = delete;
+ ListFreer &operator=(const ListFreer &) = delete;
+};
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_get_authorities_from_database) {
+ auto list = proj_get_authorities_from_database(m_ctxt);
+ ListFreer feer(list);
+ ASSERT_NE(list, nullptr);
+ ASSERT_TRUE(list[0] != nullptr);
+ EXPECT_EQ(list[0], std::string("EPSG"));
+ ASSERT_TRUE(list[1] != nullptr);
+ EXPECT_EQ(list[1], std::string("ESRI"));
+ ASSERT_TRUE(list[2] != nullptr);
+ EXPECT_EQ(list[2], std::string("IGNF"));
+ ASSERT_TRUE(list[3] != nullptr);
+ EXPECT_EQ(list[3], std::string("OGC"));
+ ASSERT_TRUE(list[4] != nullptr);
+ EXPECT_EQ(list[4], std::string("PROJ"));
+ EXPECT_EQ(list[5], nullptr);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_get_codes_from_database) {
+
+ auto listTypes =
+ std::vector<PJ_OBJ_TYPE>{PJ_OBJ_TYPE_ELLIPSOID,
+
+ PJ_OBJ_TYPE_GEODETIC_REFERENCE_FRAME,
+ PJ_OBJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME,
+ PJ_OBJ_TYPE_VERTICAL_REFERENCE_FRAME,
+ PJ_OBJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME,
+ PJ_OBJ_TYPE_DATUM_ENSEMBLE,
+
+ PJ_OBJ_TYPE_CRS,
+ PJ_OBJ_TYPE_GEODETIC_CRS,
+ PJ_OBJ_TYPE_GEOCENTRIC_CRS,
+ PJ_OBJ_TYPE_GEOGRAPHIC_CRS,
+ PJ_OBJ_TYPE_GEOGRAPHIC_2D_CRS,
+ PJ_OBJ_TYPE_GEOGRAPHIC_3D_CRS,
+ PJ_OBJ_TYPE_VERTICAL_CRS,
+ PJ_OBJ_TYPE_PROJECTED_CRS,
+ PJ_OBJ_TYPE_COMPOUND_CRS,
+ PJ_OBJ_TYPE_TEMPORAL_CRS,
+ PJ_OBJ_TYPE_BOUND_CRS,
+ PJ_OBJ_TYPE_OTHER_CRS,
+
+ PJ_OBJ_TYPE_CONVERSION,
+ PJ_OBJ_TYPE_TRANSFORMATION,
+ PJ_OBJ_TYPE_CONCATENATED_OPERATION,
+ PJ_OBJ_TYPE_OTHER_COORDINATE_OPERATION,
+
+ PJ_OBJ_TYPE_UNKNOWN};
+ for (const auto &type : listTypes) {
+ auto list = proj_get_codes_from_database(m_ctxt, "EPSG", type, true);
+ ListFreer feer(list);
+ if (type == PJ_OBJ_TYPE_TEMPORAL_CRS || type == PJ_OBJ_TYPE_BOUND_CRS ||
+ type == PJ_OBJ_TYPE_UNKNOWN) {
+ EXPECT_EQ(list, nullptr) << type;
+ } else {
+ ASSERT_NE(list, nullptr) << type;
+ ASSERT_NE(list[0], nullptr) << type;
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, conversion) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createProjectedCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ {
+ auto conv =
+ proj_obj_crs_get_coordoperation(crs, nullptr, nullptr, nullptr);
+ ASSERT_NE(conv, nullptr);
+ ObjectKeeper keeper_conv(conv);
+
+ ASSERT_EQ(
+ proj_obj_crs_get_coordoperation(conv, nullptr, nullptr, nullptr),
+ nullptr);
+ }
+
+ const char *methodName = nullptr;
+ const char *methodAuthorityName = nullptr;
+ const char *methodCode = nullptr;
+ auto conv = proj_obj_crs_get_coordoperation(
+ crs, &methodName, &methodAuthorityName, &methodCode);
+ ASSERT_NE(conv, nullptr);
+ ObjectKeeper keeper_conv(conv);
+
+ ASSERT_NE(methodName, nullptr);
+ ASSERT_NE(methodAuthorityName, nullptr);
+ ASSERT_NE(methodCode, nullptr);
+ EXPECT_EQ(methodName, std::string("Transverse Mercator"));
+ EXPECT_EQ(methodAuthorityName, std::string("EPSG"));
+ EXPECT_EQ(methodCode, std::string("9807"));
+
+ EXPECT_EQ(proj_coordoperation_get_param_count(conv), 5);
+ EXPECT_EQ(proj_coordoperation_get_param_index(conv, "foo"), -1);
+ EXPECT_EQ(proj_coordoperation_get_param_index(conv, "False easting"), 3);
+
+ EXPECT_FALSE(proj_coordoperation_get_param(conv, -1, nullptr, nullptr,
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr));
+ EXPECT_FALSE(proj_coordoperation_get_param(conv, 5, nullptr, nullptr,
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr));
+
+ const char *name = nullptr;
+ const char *nameAuthorityName = nullptr;
+ const char *nameCode = nullptr;
+ double value = 0;
+ const char *valueString = nullptr;
+ double valueUnitConvFactor = 0;
+ const char *valueUnitName = nullptr;
+ EXPECT_TRUE(proj_coordoperation_get_param(
+ conv, 3, &name, &nameAuthorityName, &nameCode, &value, &valueString,
+ &valueUnitConvFactor, &valueUnitName));
+ ASSERT_NE(name, nullptr);
+ ASSERT_NE(nameAuthorityName, nullptr);
+ ASSERT_NE(nameCode, nullptr);
+ EXPECT_EQ(valueString, nullptr);
+ ASSERT_NE(valueUnitName, nullptr);
+ EXPECT_EQ(name, std::string("False easting"));
+ EXPECT_EQ(nameAuthorityName, std::string("EPSG"));
+ EXPECT_EQ(nameCode, std::string("8806"));
+ EXPECT_EQ(value, 500000.0);
+ EXPECT_EQ(valueUnitConvFactor, 1.0);
+ EXPECT_EQ(valueUnitName, std::string("metre"));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, transformation_from_boundCRS) {
+ auto crs = proj_obj_create_from_wkt(
+ m_ctxt,
+ createBoundCRS()->exportToWKT(WKTFormatter::create().get()).c_str(),
+ nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+
+ auto transf =
+ proj_obj_crs_get_coordoperation(crs, nullptr, nullptr, nullptr);
+ ASSERT_NE(transf, nullptr);
+ ObjectKeeper keeper_transf(transf);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_coordoperation_get_grid_used) {
+ auto op = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "1312", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, true,
+ nullptr);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper(op);
+
+ EXPECT_EQ(proj_coordoperation_get_grid_used_count(op), 1);
+ const char *shortName = nullptr;
+ const char *fullName = nullptr;
+ const char *packageName = nullptr;
+ const char *url = nullptr;
+ int directDownload = 0;
+ int openLicense = 0;
+ int available = 0;
+ EXPECT_EQ(proj_coordoperation_get_grid_used(op, -1, nullptr, nullptr,
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr),
+ 0);
+ EXPECT_EQ(proj_coordoperation_get_grid_used(op, 1, nullptr, nullptr,
+ nullptr, nullptr, nullptr,
+ nullptr, nullptr),
+ 0);
+ EXPECT_EQ(proj_coordoperation_get_grid_used(
+ op, 0, &shortName, &fullName, &packageName, &url,
+ &directDownload, &openLicense, &available),
+ 1);
+ ASSERT_NE(shortName, nullptr);
+ ASSERT_NE(fullName, nullptr);
+ ASSERT_NE(packageName, nullptr);
+ ASSERT_NE(url, nullptr);
+ EXPECT_EQ(shortName, std::string("ntv1_can.dat"));
+ // EXPECT_EQ(fullName, std::string(""));
+ EXPECT_EQ(packageName, std::string("proj-datumgrid"));
+ EXPECT_TRUE(std::string(url).find(
+ "https://download.osgeo.org/proj/proj-datumgrid-") == 0)
+ << std::string(url);
+ EXPECT_EQ(directDownload, 1);
+ EXPECT_EQ(openLicense, 1);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_coordoperation_is_instanciable) {
+ auto op = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "1671", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, true,
+ nullptr);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper(op);
+ EXPECT_EQ(proj_coordoperation_is_instanciable(op), 1);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_operations) {
+ auto ctxt = proj_create_operation_factory_context(m_ctxt, nullptr);
+ ASSERT_NE(ctxt, nullptr);
+ ContextKeeper keeper_ctxt(ctxt);
+
+ auto source_crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4267", PJ_OBJ_CATEGORY_CRS, false, nullptr); // NAD27
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+
+ auto target_crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4269", PJ_OBJ_CATEGORY_CRS, false, nullptr); // NAD83
+ ASSERT_NE(target_crs, nullptr);
+ ObjectKeeper keeper_target_crs(target_crs);
+
+ proj_operation_factory_context_set_spatial_criterion(
+ ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+
+ proj_operation_factory_context_set_grid_availability_use(
+ ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+
+ auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+
+ EXPECT_EQ(proj_obj_list_get_count(res), 7);
+
+ EXPECT_EQ(proj_obj_list_get(res, -1), nullptr);
+ EXPECT_EQ(proj_obj_list_get(res, proj_obj_list_get_count(res)), nullptr);
+ auto op = proj_obj_list_get(res, 0);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper_op(op);
+
+ EXPECT_EQ(proj_obj_get_name(op), std::string("NAD27 to NAD83 (3)"));
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_operations_with_pivot) {
+
+ auto source_crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr); // WGS84
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+
+ auto target_crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "6668", PJ_OBJ_CATEGORY_CRS, false, nullptr); // JGD2011
+ ASSERT_NE(target_crs, nullptr);
+ ObjectKeeper keeper_target_crs(target_crs);
+
+ // There is no direct transformations between both
+
+ // Default behaviour: allow any pivot
+ {
+ auto ctxt = proj_create_operation_factory_context(m_ctxt, nullptr);
+ ASSERT_NE(ctxt, nullptr);
+ ContextKeeper keeper_ctxt(ctxt);
+
+ auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 1);
+ auto op = proj_obj_list_get(res, 0);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper_op(op);
+
+ EXPECT_EQ(
+ proj_obj_get_name(op),
+ std::string(
+ "Inverse of JGD2000 to WGS 84 (1) + JGD2000 to JGD2011 (2)"));
+ }
+
+ // Disallow pivots
+ {
+ auto ctxt = proj_create_operation_factory_context(m_ctxt, nullptr);
+ ASSERT_NE(ctxt, nullptr);
+ ContextKeeper keeper_ctxt(ctxt);
+ proj_operation_factory_context_set_allow_use_intermediate_crs(ctxt,
+ false);
+
+ auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 1);
+ auto op = proj_obj_list_get(res, 0);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper_op(op);
+
+ EXPECT_EQ(proj_obj_get_name(op),
+ std::string("Null geographic offset from WGS 84 to JGD2011"));
+ }
+
+ // Restrict pivot to Tokyo CRS
+ {
+ auto ctxt = proj_create_operation_factory_context(m_ctxt, "EPSG");
+ ASSERT_NE(ctxt, nullptr);
+ ContextKeeper keeper_ctxt(ctxt);
+
+ const char *pivots[] = {"EPSG", "4301", nullptr};
+ proj_operation_factory_context_set_allowed_intermediate_crs(ctxt,
+ pivots);
+ proj_operation_factory_context_set_spatial_criterion(
+ ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ proj_operation_factory_context_set_grid_availability_use(
+ ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+
+ auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 6);
+ auto op = proj_obj_list_get(res, 0);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper_op(op);
+
+ EXPECT_EQ(
+ proj_obj_get_name(op),
+ std::string(
+ "Inverse of Tokyo to WGS 84 (108) + Tokyo to JGD2011 (2)"));
+ }
+
+ // Restrict pivot to JGD2000
+ {
+ auto ctxt = proj_create_operation_factory_context(m_ctxt, nullptr);
+ ASSERT_NE(ctxt, nullptr);
+ ContextKeeper keeper_ctxt(ctxt);
+
+ const char *pivots[] = {"EPSG", "4612", nullptr};
+ proj_operation_factory_context_set_allowed_intermediate_crs(ctxt,
+ pivots);
+ proj_operation_factory_context_set_spatial_criterion(
+ ctxt, PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
+ proj_operation_factory_context_set_grid_availability_use(
+ ctxt, PROJ_GRID_AVAILABILITY_IGNORED);
+
+ auto res = proj_obj_create_operations(source_crs, target_crs, ctxt);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ // includes 2 results from ESRI
+ EXPECT_EQ(proj_obj_list_get_count(res), 4);
+ auto op = proj_obj_list_get(res, 0);
+ ASSERT_NE(op, nullptr);
+ ObjectKeeper keeper_op(op);
+
+ EXPECT_EQ(
+ proj_obj_get_name(op),
+ std::string(
+ "Inverse of JGD2000 to WGS 84 (1) + JGD2000 to JGD2011 (2)"));
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_set_database_path_null) {
+
+ EXPECT_TRUE(
+ proj_context_set_database_path(m_ctxt, nullptr, nullptr, nullptr));
+ auto source_crs = proj_obj_create_from_database(m_ctxt, "EPSG", "4326",
+ PJ_OBJ_CATEGORY_CRS, false,
+ nullptr); // WGS84
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_set_database_path_main_memory_one_aux) {
+
+ auto c_path = proj_context_get_database_path(m_ctxt);
+ ASSERT_TRUE(c_path != nullptr);
+ std::string path(c_path);
+ const char *aux_db_list[] = {path.c_str(), nullptr};
+
+ // This is super exotic and a miracle that it works. :memory: as the
+ // main DB is empty. The real stuff is in the aux_db_list. No view
+ // is created in the ':memory:' internal DB, but as there's only one
+ // aux DB its tables and views can be directly queried...
+ // If that breaks at some point, that wouldn't be a big issue.
+ // Keeping that one as I had a hard time figuring out why it worked !
+ // The real thing is tested by the C++
+ // factory::attachExtraDatabases_auxiliary
+ EXPECT_TRUE(proj_context_set_database_path(m_ctxt, ":memory:", aux_db_list,
+ nullptr));
+
+ auto source_crs = proj_obj_create_from_database(m_ctxt, "EPSG", "4326",
+ PJ_OBJ_CATEGORY_CRS, false,
+ nullptr); // WGS84
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_set_database_path_error_1) {
+
+ EXPECT_FALSE(proj_context_set_database_path(m_ctxt, "i_do_not_exist.db",
+ nullptr, nullptr));
+
+ // We will eventually re-open on the default DB
+ auto source_crs = proj_obj_create_from_database(m_ctxt, "EPSG", "4326",
+ PJ_OBJ_CATEGORY_CRS, false,
+ nullptr); // WGS84
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_set_database_path_error_2) {
+
+ const char *aux_db_list[] = {"i_do_not_exist.db", nullptr};
+ EXPECT_FALSE(
+ proj_context_set_database_path(m_ctxt, nullptr, aux_db_list, nullptr));
+
+ // We will eventually re-open on the default DB
+ auto source_crs = proj_obj_create_from_database(m_ctxt, "EPSG", "4326",
+ PJ_OBJ_CATEGORY_CRS, false,
+ nullptr); // WGS84
+ ASSERT_NE(source_crs, nullptr);
+ ObjectKeeper keeper_source_crs(source_crs);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_context_guess_wkt_dialect) {
+
+ EXPECT_EQ(proj_context_guess_wkt_dialect(nullptr, "LOCAL_CS[\"foo\"]"),
+ PJ_GUESSED_WKT1_GDAL);
+
+ EXPECT_EQ(proj_context_guess_wkt_dialect(
+ nullptr,
+ "GEOGCS[\"GCS_WGS_1984\",DATUM[\"D_WGS_1984\",SPHEROID[\"WGS_"
+ "1984\",6378137.0,298.257223563]],PRIMEM[\"Greenwich\",0.0],"
+ "UNIT[\"Degree\",0.0174532925199433]]"),
+ PJ_GUESSED_WKT1_ESRI);
+
+ EXPECT_EQ(proj_context_guess_wkt_dialect(
+ nullptr,
+ "GEOGCRS[\"WGS 84\",\n"
+ " DATUM[\"World Geodetic System 1984\",\n"
+ " ELLIPSOID[\"WGS 84\",6378137,298.257223563]],\n"
+ " CS[ellipsoidal,2],\n"
+ " AXIS[\"geodetic latitude (Lat)\",north],\n"
+ " AXIS[\"geodetic longitude (Lon)\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"),
+ PJ_GUESSED_WKT2_2018);
+
+ EXPECT_EQ(proj_context_guess_wkt_dialect(
+ nullptr,
+ "GEODCRS[\"WGS 84\",\n"
+ " DATUM[\"World Geodetic System 1984\",\n"
+ " ELLIPSOID[\"WGS 84\",6378137,298.257223563]],\n"
+ " CS[ellipsoidal,2],\n"
+ " AXIS[\"geodetic latitude (Lat)\",north],\n"
+ " AXIS[\"geodetic longitude (Lon)\",east],\n"
+ " UNIT[\"degree\",0.0174532925199433]]"),
+ PJ_GUESSED_WKT2_2015);
+
+ EXPECT_EQ(proj_context_guess_wkt_dialect(nullptr, "foo"),
+ PJ_GUESSED_NOT_WKT);
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_from_name) {
+ /*
+ PJ_OBJ_LIST PROJ_DLL *proj_obj_create_from_name(
+ PJ_CONTEXT *ctx,
+ const char *auth_name,
+ const char *searchedName,
+ const PJ_OBJ_TYPE* types,
+ size_t typesCount,
+ int approximateMatch,
+ size_t limitResultCount,
+ const char* const *options); */
+ {
+ auto res = proj_obj_create_from_name(m_ctxt, nullptr, "WGS 84", nullptr,
+ 0, false, 0, nullptr);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 4);
+ }
+ {
+ auto res = proj_obj_create_from_name(m_ctxt, "xx", "WGS 84", nullptr, 0,
+ false, 0, nullptr);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 0);
+ }
+ {
+ const PJ_OBJ_TYPE types[] = {PJ_OBJ_TYPE_GEODETIC_CRS,
+ PJ_OBJ_TYPE_PROJECTED_CRS};
+ auto res = proj_obj_create_from_name(m_ctxt, nullptr, "WGS 84", types,
+ 2, true, 10, nullptr);
+ ASSERT_NE(res, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 10);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_identify) {
+ auto obj = proj_obj_create_from_wkt(
+ m_ctxt,
+ GeographicCRS::EPSG_4807->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ {
+ auto res = proj_obj_identify(obj, nullptr, nullptr, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 1);
+ }
+ {
+ int *confidence = nullptr;
+ auto res = proj_obj_identify(obj, "EPSG", nullptr, &confidence);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(proj_obj_list_get_count(res), 1);
+ EXPECT_EQ(confidence[0], 100);
+ proj_free_int_list(confidence);
+ }
+ {
+ auto objEllps = proj_obj_create_from_wkt(
+ m_ctxt,
+ Ellipsoid::GRS1980->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperEllps(objEllps);
+ auto res = proj_obj_identify(objEllps, nullptr, nullptr, nullptr);
+ ObjListKeeper keeper_res(res);
+ EXPECT_EQ(res, nullptr);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_get_area_of_use) {
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_TRUE(proj_obj_get_area_of_use(crs, nullptr, nullptr, nullptr,
+ nullptr, nullptr));
+ const char *name = nullptr;
+ double w;
+ double s;
+ double e;
+ double n;
+ EXPECT_TRUE(proj_obj_get_area_of_use(crs, &w, &s, &e, &n, &name));
+ EXPECT_EQ(w, -180);
+ EXPECT_EQ(s, -90);
+ EXPECT_EQ(e, 180);
+ EXPECT_EQ(n, 90);
+ ASSERT_TRUE(name != nullptr);
+ EXPECT_EQ(std::string(name), "World");
+ }
+ {
+ auto obj =
+ proj_obj_create_from_user_input(m_ctxt, "+proj=longlat", nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_FALSE(proj_obj_get_area_of_use(obj, nullptr, nullptr, nullptr,
+ nullptr, nullptr));
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_coordoperation_get_accuracy) {
+ {
+ auto crs = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "4326", PJ_OBJ_CATEGORY_CRS, false, nullptr);
+ ASSERT_NE(crs, nullptr);
+ ObjectKeeper keeper(crs);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(crs), -1.0);
+ }
+ {
+ auto obj = proj_obj_create_from_database(
+ m_ctxt, "EPSG", "1170", PJ_OBJ_CATEGORY_COORDINATE_OPERATION, false,
+ nullptr);
+ ASSERT_NE(obj, nullptr);
+ ObjectKeeper keeper(obj);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(obj), 16.0);
+ }
+ {
+ auto obj =
+ proj_obj_create_from_user_input(m_ctxt, "+proj=helmert", nullptr);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ EXPECT_EQ(proj_coordoperation_get_accuracy(obj), -1.0);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_geographic_crs) {
+ {
+ auto obj = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433,
+ true);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+
+ auto objRef = proj_obj_create_from_user_input(
+ m_ctxt,
+ GeographicCRS::EPSG_4326->exportToWKT(WKTFormatter::create().get())
+ .c_str(),
+ nullptr);
+ ObjectKeeper keeperobjRef(objRef);
+ EXPECT_NE(objRef, nullptr);
+
+ EXPECT_TRUE(proj_obj_is_equivalent_to(obj, objRef, PJ_COMP_EQUIVALENT));
+ }
+ {
+ auto obj = proj_obj_create_geographic_crs(m_ctxt, nullptr, nullptr,
+ nullptr, 1.0, 0.0, nullptr,
+ 0.0, nullptr, 0.0, false);
+ ObjectKeeper keeper(obj);
+ ASSERT_NE(obj, nullptr);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_obj_create_projections) {
+
+ auto geogCRS = proj_obj_create_geographic_crs(
+ m_ctxt, "WGS 84", "World Geodetic System 1984", "WGS 84", 6378137,
+ 298.257223563, "Greenwich", 0.0, "Degree", 0.0174532925199433, true);
+ ObjectKeeper keepergeogCRS(geogCRS);
+ ASSERT_NE(geogCRS, nullptr);
+
+ /* BEGIN: Generated by scripts/create_c_api_projections.py*/
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_UTM(geogCRS, nullptr, 0, 0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_TransverseMercator(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_GaussSchreiberTransverseMercator(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_TransverseMercatorSouthOriented(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_TwoPointEquidistant(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_TunisiaMappingGrid(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_AlbersEqualArea(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_LambertConicConformal_1SP(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_LambertConicConformal_2SP(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_LambertConicConformal_2SP_Michigan(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
+ 0.0174532925199433, "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_LambertConicConformal_2SP_Belgium(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree",
+ 0.0174532925199433, "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_AzimuthalEquidistant(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_GuamProjection(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Bonne(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_LambertCylindricalEqualAreaSpherical(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_LambertCylindricalEqualArea(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_CassiniSoldner(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EquidistantConic(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertI(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertII(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertIII(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertIV(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertV(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EckertVI(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EquidistantCylindrical(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_EquidistantCylindricalSpherical(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Gall(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_GoodeHomolosine(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_InterruptedGoodeHomolosine(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_GeostationarySatelliteSweepX(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_GeostationarySatelliteSweepY(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Gnomonic(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_HotineObliqueMercatorVariantA(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
+ 0.0174532925199433, "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_HotineObliqueMercatorVariantB(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree",
+ 0.0174532925199433, "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_HotineObliqueMercatorTwoPointNaturalOrigin(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, 0, "Degree",
+ 0.0174532925199433, "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_InternationalMapWorldPolyconic(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_KrovakNorthOriented(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Krovak(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_LambertAzimuthalEqualArea(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_MillerCylindrical(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_MercatorVariantA(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_MercatorVariantB(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_PopularVisualisationPseudoMercator(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Mollweide(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_NewZealandMappingGrid(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_ObliqueStereographic(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Orthographic(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_AmericanPolyconic(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_PolarStereographicVariantA(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_PolarStereographicVariantB(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Robinson(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Sinusoidal(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_Stereographic(
+ geogCRS, nullptr, 0, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_VanDerGrinten(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerI(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerII(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerIII(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerIV(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerV(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerVI(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_WagnerVII(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS =
+ proj_obj_create_projected_crs_QuadrilateralizedSphericalCube(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433,
+ "Metre", 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_SphericalCrossTrackHeight(
+ geogCRS, nullptr, 0, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ {
+ auto projCRS = proj_obj_create_projected_crs_EqualEarth(
+ geogCRS, nullptr, 0, 0, 0, "Degree", 0.0174532925199433, "Metre",
+ 1.0);
+ ObjectKeeper keeper_projCRS(projCRS);
+ ASSERT_NE(projCRS, nullptr);
+ }
+ /* END: Generated by scripts/create_c_api_projections.py*/
+}
+
+} // namespace