Skip to content

Commit 8b9eedc

Browse files
authored
Merge pull request #1873 from joto/refactor-projection-use
Refactor projection use
2 parents 6be98ba + 6baba15 commit 8b9eedc

File tree

5 files changed

+31
-17
lines changed

5 files changed

+31
-17
lines changed

src/flex-lua-geom.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,8 @@ static int geom_transform(lua_State *lua_state)
223223
throw std::runtime_error{
224224
"Can not transform already transformed geometry."};
225225
}
226-
auto const proj = reprojection::create_projection(srid);
227-
228226
auto *geom = create_lua_geometry_object(lua_state);
229-
geom::transform(geom, *input_geometry, *proj);
227+
geom::transform(geom, *input_geometry, get_projection(srid));
230228
} catch (...) {
231229
return luaL_error(lua_state, "Unknown error in 'transform()'.\n");
232230
}

src/flex-write.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -473,9 +473,8 @@ void flex_write_column(lua_State *lua_state,
473473
expire->from_geometry_if_3857(*geom);
474474
copy_mgr->add_hex_geom(geom_to_ewkb(*geom, wrap_multi));
475475
} else {
476-
auto const proj =
477-
reprojection::create_projection(column.srid());
478-
auto const tgeom = geom::transform(*geom, *proj);
476+
auto const &proj = get_projection(column.srid());
477+
auto const tgeom = geom::transform(*geom, proj);
479478
expire->from_geometry_if_3857(tgeom);
480479
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom, wrap_multi));
481480
}
@@ -512,8 +511,7 @@ void flex_write_row(lua_State *lua_state, table_connection_t *table_connection,
512511
geom::geometry_t projected_geom;
513512
geom::geometry_t const *output_geom = &geom;
514513
if (srid && geom.srid() != srid) {
515-
auto const proj = reprojection::create_projection(srid);
516-
projected_geom = geom::transform(geom, *proj);
514+
projected_geom = geom::transform(geom, get_projection(srid));
517515
output_geom = &projected_geom;
518516
}
519517

@@ -543,11 +541,8 @@ void flex_write_row(lua_State *lua_state, table_connection_t *table_connection,
543541
} else if (column.srid() == srid) {
544542
area = geom::area(projected_geom);
545543
} else {
546-
// XXX there is some overhead here always dynamically
547-
// creating the same projection object. Needs refactoring.
548-
auto const mproj =
549-
reprojection::create_projection(column.srid());
550-
area = geom::area(geom::transform(geom, *mproj));
544+
auto const &mproj = get_projection(column.srid());
545+
area = geom::area(geom::transform(geom, mproj));
551546
}
552547
copy_mgr->add_column(area);
553548
}

src/output-pgsql.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ static double calculate_area(bool reproject_area,
4848
geom::geometry_t const &geom4326,
4949
geom::geometry_t const &geom)
5050
{
51+
static thread_local auto const proj3857 =
52+
reprojection::create_projection(3857);
53+
5154
if (reproject_area) {
52-
// XXX there is some overhead here always dynamically
53-
// creating the same projection object. Needs refactoring.
54-
auto const ogeom =
55-
geom::transform(geom4326, *reprojection::create_projection(3857));
55+
auto const ogeom = geom::transform(geom4326, *proj3857);
5656
return geom::area(ogeom);
5757
}
5858
return geom::area(geom);

src/reprojection.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,18 @@ std::shared_ptr<reprojection> reprojection::create_projection(int srs)
8686

8787
return make_generic_projection(srs);
8888
}
89+
90+
reprojection const &get_projection(int srs)
91+
{
92+
// In almost all cases there will be only one or two projections used, so
93+
// storing them in a vector and doing linear search is totally fine.
94+
static std::vector<std::shared_ptr<reprojection>> projections;
95+
96+
for (auto const &p : projections) {
97+
if (p->target_srs() == srs) {
98+
return *p;
99+
}
100+
}
101+
102+
return *projections.emplace_back(reprojection::create_projection(srs));
103+
}

src/reprojection.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,10 @@ class reprojection
7171

7272
std::string get_proj_version();
7373

74+
/**
75+
* Get projection object for given srs. Objects are only created once and
76+
* then cached.
77+
*/
78+
reprojection const &get_projection(int srs);
79+
7480
#endif // OSM2PGSQL_REPROJECTION_HPP

0 commit comments

Comments
 (0)