source: subversion/applications/utils/export/osm2pgsql/build_geometry.cpp @ 3210

Last change on this file since 3210 was 2827, checked in by jonb, 13 years ago

osm2pgsql - make experimental version current, move previous implementation to legacy

File size: 4.9 KB
Line 
1/*
2#-----------------------------------------------------------------------------
3# Part of osm2pgsql utility
4#-----------------------------------------------------------------------------
5# By Artem Pavlenko, Copyright 2007
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License
9# as published by the Free Software Foundation; either version 2
10# of the License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20#-----------------------------------------------------------------------------
21*/
22
23#include <iostream>
24
25#include <geos_c.h>
26
27#if (GEOS_VERSION_MAJOR==3)
28/* geos trunk (3.0.0rc) */
29#include <geos/geom/GeometryFactory.h>
30#include <geos/geom/CoordinateSequenceFactory.h>
31#include <geos/geom/Geometry.h>
32#include <geos/geom/LineString.h>
33#include <geos/geom/LinearRing.h>
34#include <geos/geom/MultiLineString.h>
35#include <geos/geom/Polygon.h>
36#include <geos/geom/Point.h>
37#include <geos/io/WKTReader.h>
38#include <geos/io/WKTWriter.h>
39#include <geos/opLinemerge.h>
40using namespace geos::geom;
41using namespace geos::io;
42using namespace geos::operation::linemerge;
43#else
44/* geos-2.2.3 */
45#include <geos/geom.h>
46#include <geos/io.h>
47#include <geos/opLinemerge.h>
48using namespace geos;
49#endif
50
51#include "build_geometry.h"
52
53typedef std::auto_ptr<Geometry> geom_ptr;
54
55struct Segment
56{
57      Segment(double x0_,double y0_,double x1_,double y1_)
58         :x0(x0_),y0(y0_),x1(x1_),y1(y1_) {}
59
60      double x0;
61      double y0;
62      double x1;
63      double y1;
64};
65
66struct Centroid
67{
68        Centroid(double x_, double y_)
69          : x(x_), y(y_) {}
70
71        Centroid(Geometry *geom) {
72                Point * pt = geom->getCentroid();
73                x = pt->getX();
74                y = pt->getY();
75                //cout << "Center: " << x << "," << y << endl;
76        }
77        double x, y;
78};
79
80static std::vector<Segment> segs;
81static std::vector<std::string> wkts;
82static std::vector<Centroid> centroids;
83
84
85int is_simple(const char* wkt)
86{
87   GeometryFactory factory;
88   WKTReader reader(&factory);
89   geom_ptr geom(reader.read(wkt));
90   if (geom->isSimple()) return 1;
91   return 0;
92}
93
94void add_segment(double x0,double y0,double x1,double y1)
95{
96   segs.push_back(Segment(x0,y0,x1,y1));
97}
98
99char * get_wkt(size_t index)
100{
101//   return wkts[index].c_str();
102        char *result;
103        result = (char*) std::malloc( wkts[index].length() + 1);
104        std::strcpy(result, wkts[index].c_str() );
105        return result;
106}
107
108void get_centroid(size_t index, double *y, double *x)
109{
110        *x = centroids[index].x;
111        *y = centroids[index].y;
112}
113void clear_wkts()
114{
115   wkts.clear();
116   centroids.clear();
117}
118
119size_t build_geometry(int polygon)
120{
121   size_t wkt_size = 0;
122   GeometryFactory factory;
123   geom_ptr segment(0);
124   std::auto_ptr<std::vector<Geometry*> > lines(new std::vector<Geometry*>);
125   std::vector<Segment>::const_iterator pos=segs.begin();
126   std::vector<Segment>::const_iterator end=segs.end();
127   bool first=true;
128   try  {
129     while (pos != end)
130       {
131         if (pos->x0 != pos->x1 || pos->y0 != pos->y1)
132           {
133             std::auto_ptr<CoordinateSequence> coords(factory.getCoordinateSequenceFactory()->create(0,2));
134             coords->add(Coordinate(pos->x0,pos->y0));
135             coords->add(Coordinate(pos->x1,pos->y1));
136             geom_ptr linestring(factory.createLineString(coords.release()));
137             if (first)
138               {
139                 segment = linestring;
140                 first=false;
141               }
142             else
143               {
144                 lines->push_back(linestring.release());
145               }
146           }
147         ++pos;
148       }
149     
150     segs.clear();
151     
152     if (segment.get())
153       {
154         geom_ptr mline (factory.createMultiLineString(lines.release()));
155         geom_ptr noded (segment->Union(mline.get()));
156         LineMerger merger;
157         merger.add(noded.get());
158         std::auto_ptr<std::vector<LineString *> > merged(merger.getMergedLineStrings());
159         WKTWriter writer;
160         
161         for (unsigned i=0 ;i < merged->size(); ++i)
162           {
163             std::auto_ptr<LineString> pline ((*merged ) [i]);
164             
165             if (polygon == 1 && pline->getNumPoints() > 3 && pline->isClosed())
166               {
167                 std::auto_ptr<LinearRing> ring(factory.createLinearRing(pline->getCoordinates()));
168                 geom_ptr poly(factory.createPolygon(ring.release(),0));
169                 std::string text = writer.write(poly.get());
170
171                 wkts.push_back(text);
172                 centroids.push_back(Centroid(poly.get()));
173                 ++wkt_size;
174               }
175             else
176               {
177                 std::string text = writer.write(pline.get());
178                 wkts.push_back(text);
179                 centroids.push_back(Centroid(0,0));
180                 ++wkt_size;
181               }
182           }
183       }
184   }
185   catch (...)
186     {
187       std::cerr << "excepton caught \n";
188       wkt_size = 0;
189     }
190   return wkt_size;
191}
192
Note: See TracBrowser for help on using the repository browser.