mirror of
https://github.com/osm2pgsql-dev/osm2pgsql.git
synced 2025-07-25 16:06:14 +00:00
256 lines
8.4 KiB
C++
256 lines
8.4 KiB
C++
/**
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*
|
|
* This file is part of osm2pgsql (https://osm2pgsql.org/).
|
|
*
|
|
* Copyright (C) 2006-2025 by the osm2pgsql developer community.
|
|
* For a full list of authors see the git log.
|
|
*/
|
|
|
|
#include <catch.hpp>
|
|
|
|
#include "geom-functions.hpp"
|
|
#include "geom-output.hpp"
|
|
#include "geom.hpp"
|
|
#include "projection.hpp"
|
|
#include "reprojection.hpp"
|
|
|
|
namespace {
|
|
|
|
void check(geom::point_t a, geom::point_t b)
|
|
{
|
|
REQUIRE(a.x() == Approx(b.x()));
|
|
REQUIRE(a.y() == Approx(b.y()));
|
|
}
|
|
|
|
} // anonymous namespace
|
|
|
|
double const X55 = 612257.1993630046; // lon 5.5
|
|
double const Y44 = 490287.90003313165; // lat 4.4
|
|
double const X33 = 367354.31961780274; // lon 3.3
|
|
double const Y22 = 244963.0806270098; // lat 2.2
|
|
|
|
double const X0 = 0; // lon 0.0
|
|
double const Y0 = 0; // lat 0.0
|
|
double const X1 = 111319.49079327357; // lon 1.0
|
|
double const Y1 = 111325.14286638486; // lat 1.0
|
|
|
|
double const X01 = 11131.949079327358; // lon 0.1
|
|
double const Y01 = 11131.954730972562; // lat 0.1
|
|
double const X09 = 100187.54171394622; // lon 0.9
|
|
double const Y09 = 100191.66201561989; // lat 0.9
|
|
|
|
TEST_CASE("Transform geom::null_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t const geom{};
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_null());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
}
|
|
|
|
TEST_CASE("Transform geom::point_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t const geom{geom::point_t{5.5, 4.4}};
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_point());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
check(result.get<geom::point_t>(),
|
|
geom::point_t{612257.1993630046, 490287.90003313165});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::linestring_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t const geom{geom::linestring_t{{5.5, 4.4}, {3.3, 2.2}}};
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_linestring());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &r = result.get<geom::linestring_t>();
|
|
check(r[0], geom::point_t{X55, Y44});
|
|
check(r[1], geom::point_t{X33, Y22});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::polygon_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t geom{
|
|
geom::polygon_t{geom::ring_t{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}}};
|
|
geom.get<geom::polygon_t>().add_inner_ring(geom::ring_t{
|
|
{0.1, 0.1}, {0.1, 0.9}, {0.9, 0.9}, {0.9, 0.1}, {0.1, 0.1}});
|
|
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_polygon());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &polygon = result.get<geom::polygon_t>();
|
|
auto const &outer = polygon.outer();
|
|
|
|
REQUIRE(outer.size() == 5);
|
|
check(outer[0], geom::point_t{X0, Y0});
|
|
check(outer[1], geom::point_t{X0, Y1});
|
|
check(outer[2], geom::point_t{X1, Y1});
|
|
check(outer[3], geom::point_t{X1, Y0});
|
|
check(outer[4], geom::point_t{X0, Y0});
|
|
|
|
REQUIRE(polygon.inners().size() == 1);
|
|
auto const &inner = polygon.inners()[0];
|
|
REQUIRE(inner.size() == 5);
|
|
check(inner[0], geom::point_t{X01, Y01});
|
|
check(inner[1], geom::point_t{X01, Y09});
|
|
check(inner[2], geom::point_t{X09, Y09});
|
|
check(inner[3], geom::point_t{X09, Y01});
|
|
check(inner[4], geom::point_t{X01, Y01});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::multipoint_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t geom{geom::multipoint_t{}};
|
|
auto &mp = geom.get<geom::multipoint_t>();
|
|
mp.add_geometry({5.5, 4.4});
|
|
mp.add_geometry({3.3, 2.2});
|
|
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_multipoint());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &rmp = result.get<geom::multipoint_t>();
|
|
REQUIRE(rmp.num_geometries() == 2);
|
|
check(rmp[0], geom::point_t{X55, Y44});
|
|
check(rmp[1], geom::point_t{X33, Y22});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::multilinestring_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t geom{geom::multilinestring_t{}};
|
|
auto &ml = geom.get<geom::multilinestring_t>();
|
|
ml.add_geometry(geom::linestring_t{{0, 0}, {5.5, 4.4}});
|
|
ml.add_geometry(geom::linestring_t{{0, 0}, {3.3, 2.2}});
|
|
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_multilinestring());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &rml = result.get<geom::multilinestring_t>();
|
|
REQUIRE(rml.num_geometries() == 2);
|
|
|
|
REQUIRE(rml[0].size() == 2);
|
|
check(rml[0][0], geom::point_t{X0, Y0});
|
|
check(rml[0][1], geom::point_t{X55, Y44});
|
|
|
|
REQUIRE(rml[1].size() == 2);
|
|
check(rml[1][0], geom::point_t{X0, Y0});
|
|
check(rml[1][1], geom::point_t{X33, Y22});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::multipolygon_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t geom{geom::multipolygon_t{}};
|
|
auto &mp = geom.get<geom::multipolygon_t>();
|
|
mp.add_geometry(
|
|
geom::polygon_t{geom::ring_t{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}});
|
|
mp.add_geometry(geom::polygon_t{geom::ring_t{
|
|
{0.1, 0.1}, {0.1, 0.9}, {0.9, 0.9}, {0.9, 0.1}, {0.1, 0.1}}});
|
|
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_multipolygon());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &rmp = result.get<geom::multipolygon_t>();
|
|
REQUIRE(rmp.num_geometries() == 2);
|
|
|
|
auto const &first = rmp[0].outer();
|
|
REQUIRE(first.size() == 5);
|
|
check(first[0], geom::point_t{X0, Y0});
|
|
check(first[1], geom::point_t{X0, Y1});
|
|
check(first[2], geom::point_t{X1, Y1});
|
|
check(first[3], geom::point_t{X1, Y0});
|
|
check(first[4], geom::point_t{X0, Y0});
|
|
|
|
auto const &second = rmp[1].outer();
|
|
REQUIRE(second.size() == 5);
|
|
check(second[0], geom::point_t{X01, Y01});
|
|
check(second[1], geom::point_t{X01, Y09});
|
|
check(second[2], geom::point_t{X09, Y09});
|
|
check(second[3], geom::point_t{X09, Y01});
|
|
check(second[4], geom::point_t{X01, Y01});
|
|
}
|
|
|
|
TEST_CASE("Transform geom::collection_t", "[NoDB]")
|
|
{
|
|
auto const &reprojection =
|
|
reprojection::create_projection(PROJ_SPHERE_MERC);
|
|
|
|
geom::geometry_t geom{geom::collection_t{}};
|
|
auto &c = geom.get<geom::collection_t>();
|
|
c.add_geometry(geom::geometry_t{geom::point_t{5.5, 4.4}});
|
|
c.add_geometry(
|
|
geom::geometry_t{geom::linestring_t{{0.0, 0.0}, {5.5, 4.4}}});
|
|
c.add_geometry(geom::geometry_t{
|
|
geom::polygon_t{geom::ring_t{{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}}}});
|
|
|
|
{
|
|
geom::geometry_t mpgeom{geom::multipoint_t{}};
|
|
auto &mp = mpgeom.get<geom::multipoint_t>();
|
|
mp.add_geometry({5.5, 4.4});
|
|
mp.add_geometry({3.3, 2.2});
|
|
c.add_geometry(std::move(mpgeom));
|
|
}
|
|
|
|
auto const result = geom::transform(geom, *reprojection);
|
|
REQUIRE(result.is_collection());
|
|
REQUIRE(result.srid() == PROJ_SPHERE_MERC);
|
|
|
|
auto const &rc = result.get<geom::collection_t>();
|
|
REQUIRE(rc.num_geometries() == 4);
|
|
|
|
REQUIRE(rc[0].is_point());
|
|
REQUIRE(rc[0].srid() == 0);
|
|
auto const &rc0 = rc[0].get<geom::point_t>();
|
|
check(rc0, geom::point_t{X55, Y44});
|
|
|
|
REQUIRE(rc[1].is_linestring());
|
|
REQUIRE(rc[1].srid() == 0);
|
|
auto const &rc1 = rc[1].get<geom::linestring_t>();
|
|
REQUIRE(rc1.size() == 2);
|
|
check(rc1[0], geom::point_t{X0, Y0});
|
|
check(rc1[1], geom::point_t{X55, Y44});
|
|
|
|
REQUIRE(rc[2].is_polygon());
|
|
REQUIRE(rc[2].srid() == 0);
|
|
auto const &rc2 = rc[2].get<geom::polygon_t>();
|
|
REQUIRE(rc2.outer().size() == 5);
|
|
check(rc2.outer()[0], geom::point_t{X0, Y0});
|
|
check(rc2.outer()[1], geom::point_t{X0, Y1});
|
|
check(rc2.outer()[2], geom::point_t{X1, Y1});
|
|
check(rc2.outer()[3], geom::point_t{X1, Y0});
|
|
check(rc2.outer()[4], geom::point_t{X0, Y0});
|
|
|
|
REQUIRE(rc[3].is_multipoint());
|
|
REQUIRE(rc[3].srid() == 0);
|
|
auto const &rc3 = rc[3].get<geom::multipoint_t>();
|
|
REQUIRE(rc3.num_geometries() == 2);
|
|
check(rc3[0], geom::point_t{X55, Y44});
|
|
check(rc3[1], geom::point_t{X33, Y22});
|
|
}
|