@@ -59,75 +59,76 @@ std::size_t num_geometries(geometry_t const &geom)
5959
6060namespace {
6161
62+ void set_to_same_type (geometry_t *output, geometry_t const &input)
63+ {
64+ input.visit (overloaded{[&](auto in) { output->set <decltype (in)>(); }});
65+ }
66+
6267class transform_visitor
6368{
6469public:
65- explicit transform_visitor (reprojection const *reprojection)
66- : m_reprojection(reprojection)
70+ explicit transform_visitor (geometry_t *output,
71+ reprojection const *reprojection)
72+ : m_output(output), m_reprojection(reprojection)
6773 {}
6874
69- geometry_t operator ()(geom::nullgeom_t const & /* geom*/ ) const
70- {
71- return {};
72- }
75+ void operator ()(nullgeom_t const & /* input*/ ) const {}
7376
74- geometry_t operator ()(geom:: point_t const &geom ) const
77+ void operator ()(point_t const &input ) const
7578 {
76- return geometry_t { project (geom), srid ()} ;
79+ m_output-> get < point_t >() = project (input) ;
7780 }
7881
79- geometry_t operator ()(geom:: linestring_t const &geom ) const
82+ void operator ()(linestring_t const &input ) const
8083 {
81- geometry_t output{linestring_t {}, srid ()};
82- transform_points (&output.get <linestring_t >(), geom);
83- return output;
84+ transform_points (&m_output->get <linestring_t >(), input);
8485 }
8586
86- geometry_t operator ()(geom:: polygon_t const &geom ) const
87+ void operator ()(polygon_t const &input ) const
8788 {
88- geometry_t output{polygon_t {}, srid ()};
89- transform_polygon (&output.get <polygon_t >(), geom);
90- return output;
89+ transform_polygon (&m_output->get <polygon_t >(), input);
9190 }
9291
93- geometry_t operator ()(geom:: multipoint_t const & /* geom */ ) const
92+ void operator ()(multipoint_t const &input ) const
9493 {
95- assert (false );
96- return {};
94+ auto &m = m_output->get <multipoint_t >();
95+ m.reserve (input.num_geometries ());
96+ for (auto const point : input) {
97+ m.add_geometry (project (point));
98+ }
9799 }
98100
99- geometry_t operator ()(geom:: multilinestring_t const &geom ) const
101+ void operator ()(multilinestring_t const &input ) const
100102 {
101- geometry_t output{multilinestring_t {}, srid ()};
102-
103- for (auto const &line : geom) {
104- transform_points (&output.get <multilinestring_t >().add_geometry (),
105- line);
103+ auto &m = m_output->set <multilinestring_t >();
104+ m.reserve (input.num_geometries ());
105+ for (auto const &line : input) {
106+ transform_points (&m.add_geometry (), line);
106107 }
107-
108- return output;
109108 }
110109
111- geometry_t operator ()(geom:: multipolygon_t const &geom ) const
110+ void operator ()(multipolygon_t const &input ) const
112111 {
113- geometry_t output{multipolygon_t {}, srid ()};
114-
115- for (auto const &polygon : geom) {
116- transform_polygon (&output.get <multipolygon_t >().add_geometry (),
117- polygon);
112+ auto &m = m_output->set <multipolygon_t >();
113+ m.reserve (input.num_geometries ());
114+ for (auto const &polygon : input) {
115+ transform_polygon (&m.add_geometry (), polygon);
118116 }
119-
120- return output;
121117 }
122118
123- geometry_t operator ()(geom:: collection_t const & /* geom */ ) const
119+ void operator ()(collection_t const &input ) const
124120 {
125- return {}; // XXX not implemented
121+ auto &m = m_output->get <collection_t >();
122+ m.reserve (input.num_geometries ());
123+ for (auto const &geom : input) {
124+ auto &new_geom = m.add_geometry ();
125+ set_to_same_type (&new_geom, geom);
126+ new_geom.set_srid (0 );
127+ geom.visit (transform_visitor{&new_geom, m_reprojection});
128+ }
126129 }
127130
128131private:
129- int srid () const noexcept { return m_reprojection->target_srs (); }
130-
131132 point_t project (point_t point) const
132133 {
133134 return m_reprojection->reproject (point);
@@ -152,16 +153,28 @@ class transform_visitor
152153 }
153154 }
154155
156+ geometry_t *m_output;
155157 reprojection const *m_reprojection;
156158
157159}; // class transform_visitor
158160
159161} // anonymous namespace
160162
161- geometry_t transform (geometry_t const &geom, reprojection const &reprojection)
163+ void transform (geometry_t *output, geometry_t const &input,
164+ reprojection const &reprojection)
162165{
163- assert (geom.srid () == 4326 );
164- return geom.visit (transform_visitor{&reprojection});
166+ assert (input.srid () == 4326 );
167+
168+ set_to_same_type (output, input);
169+ output->set_srid (reprojection.target_srs ());
170+ input.visit (transform_visitor{output, &reprojection});
171+ }
172+
173+ geometry_t transform (geometry_t const &input, reprojection const &reprojection)
174+ {
175+ geometry_t output;
176+ transform (&output, input, reprojection);
177+ return output;
165178}
166179
167180namespace {
0 commit comments