source: subversion/utils/export/osm2pgsql/build_geometry.cpp @ 2498

Last change on this file since 2498 was 2330, checked in by jonb, 13 years ago

Automatic GEOS version detection

File size: 4.2 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#include <geos_c.h>
25
26#if (GEOS_VERSION_MAJOR==3)
27/* geos trunk (3.0.0rc) */
28#include <geos/geom/GeometryFactory.h>
29#include <geos/geom/CoordinateSequenceFactory.h>
30#include <geos/geom/Geometry.h>
31#include <geos/geom/LineString.h>
32#include <geos/geom/LinearRing.h>
33#include <geos/geom/MultiLineString.h>
34#include <geos/geom/Polygon.h>
35#include <geos/io/WKTReader.h>
36#include <geos/io/WKTWriter.h>
37#include <geos/opLinemerge.h>
38using namespace geos::geom;
39using namespace geos::io;
40using namespace geos::operation::linemerge;
41#else
42/* geos-2.2 */
43#include <geos/geom.h>
44#include <geos/io.h>
45#include <geos/opLinemerge.h>
46using namespace geos;
47#endif
48
49#include "build_geometry.h"
50
51
52struct Segment
53{
54      Segment(double x0_,double y0_,double x1_,double y1_)
55         :x0(x0_),y0(y0_),x1(x1_),y1(y1_) {}
56     
57      double x0;
58      double y0;
59      double x1;
60      double y1;
61};
62
63static std::vector<Segment> segs;
64static std::vector<std::string> wkts;
65
66typedef std::auto_ptr<Geometry> geom_ptr;
67
68int is_simple(const char* wkt)
69{
70   GeometryFactory factory;
71   WKTReader reader(&factory);
72   geom_ptr geom(reader.read(wkt));
73   if (geom->isSimple()) return 1;
74   return 0;
75}
76
77void add_segment(double x0,double y0,double x1,double y1)
78{
79   segs.push_back(Segment(x0,y0,x1,y1));
80}
81
82const char * get_wkt(size_t index)
83{
84   return wkts[index].c_str();
85}
86
87void clear_wkts()
88{
89   wkts.clear();
90}
91
92size_t build_geometry(int polygon)
93{
94   size_t wkt_size = 0;
95   GeometryFactory factory;
96   geom_ptr segment(0);
97   std::auto_ptr<std::vector<Geometry*> > lines(new std::vector<Geometry*>);
98   std::vector<Segment>::const_iterator pos=segs.begin();
99   std::vector<Segment>::const_iterator end=segs.end();
100   bool first=true;
101   try  {
102     while (pos != end)
103       {
104         if (pos->x0 != pos->x1 || pos->y0 != pos->y1)
105           {
106             std::auto_ptr<CoordinateSequence> coords(factory.getCoordinateSequenceFactory()->create(0,2));
107             coords->add(Coordinate(pos->x0,pos->y0));
108             coords->add(Coordinate(pos->x1,pos->y1));
109             geom_ptr linestring(factory.createLineString(coords.release()));
110             if (first)
111               {
112                 segment = linestring;
113                 first=false;
114               }
115             else
116               {
117                 lines->push_back(linestring.release());
118               }
119           }
120         ++pos;
121       }
122     
123     segs.clear();
124     
125     if (segment.get())
126       {
127         geom_ptr mline (factory.createMultiLineString(lines.release()));
128         geom_ptr noded (segment->Union(mline.get()));
129         LineMerger merger;
130         merger.add(noded.get());
131         std::auto_ptr<std::vector<LineString *> > merged(merger.getMergedLineStrings());
132         WKTWriter writer;
133         
134         for (unsigned i=0 ;i < merged->size(); ++i)
135           {
136             std::auto_ptr<LineString> pline ((*merged ) [i]);
137             
138             if (polygon == 1 && pline->getNumPoints() > 3 && pline->isClosed())
139               {
140                 std::auto_ptr<LinearRing> ring(factory.createLinearRing(pline->getCoordinates()));
141                 geom_ptr poly(factory.createPolygon(ring.release(),0));
142                 std::string text = writer.write(poly.get());
143                 
144                 wkts.push_back(text);
145                 ++wkt_size;
146               }
147             else
148               {
149                 std::string text = writer.write(pline.get());
150                 wkts.push_back(text);
151                 ++wkt_size;
152               }
153           }
154       }
155   }
156   catch (...)
157     {
158       std::cerr << "excepton caught \n";
159       wkt_size = 0;
160     }
161   return wkt_size;
162}
163
Note: See TracBrowser for help on using the repository browser.