source: subversion/applications/lib/libosm/Components.cpp @ 11743

Last change on this file since 11743 was 11743, checked in by nienhueser, 11 years ago

Remove cleanWays(), doesn't seem to be useful anymore

File size: 9.2 KB
Line 
1/*
2
3Copyright (C) 2005 Nick Whitelegg, Hogweed Software, nick@hogweed.org
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
18
19 */
20// 180306 updated for 0.3
21#include "Components.h"
22#include <iostream>
23#include <fstream>
24#include <iomanip>
25#include <string>
26#include <sstream>
27#include <shapefil.h>
28#include "Node.h"
29#include "Parser.h"
30#include "Way.h"
31#include <vector>
32#include <fstream>
33#include "llgr.h"
34#include "FeatureClassification.h"
35#include "FeaturesParser.h"
36
37#include "ccoord/LatLng.h"
38#include "ccoord/OSRef.h"
39
40using std::endl;
41using std::setw;
42using std::setfill;
43using std::setprecision;
44using std::cerr;
45
46using std::cout;
47
48namespace OSM
49{
50
51
52Components::Components() :
53        nodes(), ways(), nextNodeId(-1), nextSegmentId(-1), nextWayId(-1),
54                        destroyComponents(true)
55{
56        nodeIterator = nodes.begin();
57        wayIterator = ways.begin();
58}
59
60Components::~Components()
61{
62        if (destroyComponents)
63                destroy();
64}
65
66void Components::setDestroyComponents(bool b)
67{
68        destroyComponents = b;
69}
70
71void Components::destroy()
72{
73    for(std::map<int,Node*>::iterator i=nodes.begin(); i!=nodes.end(); i++)
74        delete i->second;
75
76    for(std::map<int,Way*>::iterator i=ways.begin(); i!=ways.end(); i++)
77        delete i->second;
78}
79
80int Components::addNode(Node *n)
81{
82        int realID = n->id() ? n->id() : nextNodeId--;
83        n->setId(realID);
84        nodes[realID] = n;
85        return realID;
86}
87
88int Components::addWay(Way *w)
89{
90        int realID = w->id() ? w->id() : nextWayId--;
91        w->setId(realID);
92        ways[realID] = w;
93        return realID;
94}
95
96Node *Components::getNode(int i)
97{
98        return (nodes.find(i) != nodes.end()) ? nodes[i] : NULL;
99}
100
101Way *Components::getWay(int i)
102{
103        return (ways.find(i) != ways.end()) ? ways[i] : NULL;
104}
105
106Node *Components::nextNode()
107{
108        Node *n = (nodeIterator == nodes.end()) ? NULL : nodeIterator->second;
109        nodeIterator++;
110        return n;
111}
112
113Way *Components::nextWay()
114{
115        Way *w = (wayIterator == ways.end()) ? NULL : wayIterator->second;
116        wayIterator++;
117        return w;
118}
119
120void Components::rewindNodes()
121{
122        nodeIterator = nodes.begin();
123}
124void Components::rewindWays()
125{
126        wayIterator = ways.begin();
127}
128bool Components::hasMoreNodes() const
129{
130        return nodeIterator != nodes.end();
131}
132bool Components::hasMoreWays() const
133{
134        return wayIterator != ways.end();
135}
136
137// Return a vector of the coordinates of all the points making up a way,
138// in lon-lat order.
139// WILL ONLY WORK IF THE WAY IS STORED SENSIBLY, i.e. ALL SEGMENTS ALIGNED IN
140// SAME DIRECTION AND IN LOGICAL ORDER !!!
141
142std::vector<double> Components::getWayCoords(int id)
143{
144        std::vector<double> coords;
145        Node *n1;
146        Way *w = getWay(id);
147        if(w)
148        {
149                for(int count=0; count<w->nNodes(); count++)
150                {
151                        n1 = getNode(w->getNode(count));
152                        if(n1)
153                        {
154                                        coords.push_back(n1->getLon());
155                                        coords.push_back(n1->getLat());
156                        }
157                }
158        }
159        return coords;
160}
161
162// 310107 adds null node IDs too
163std::vector<int> Components::getWayNodes(int wayid)
164{
165        std::vector<int> ids;
166        Way *w = getWay(wayid);
167        Node *n = 0;
168        if(w)
169        {
170                for(int count=0; count<w->nNodes(); count++)
171                {
172                        n = getNode(w->getNode(count));
173                        if(n)// && getNode(s->firstNode()) && getNode(s->secondNode()))
174                        {
175                                ids.push_back(n->id());
176                        }
177                }
178        }
179        return ids;
180}
181
182// get all way tags
183// this could be used eg. to work out how many columns are needed in a shapefile
184std::set<std::string> Components::getWayTags
185        (FeatureClassification *classification, bool doArea)
186{
187        Way *w;
188        std::set<std::string> tags;
189        std::vector<std::string> curTags;
190
191        rewindWays();
192        while(hasMoreWays())
193        {
194                w = nextWay();
195                if ( (classification==NULL) ||
196                        (doArea==true && classification->getFeatureClass(w)=="area") ||
197                        (doArea==false && classification->getFeatureClass(w)!="area") )
198                {
199                        curTags = w->getTags();
200                        for(unsigned int count=0; count<curTags.size(); count++)
201                                tags.insert(curTags[count]);
202                }
203        }
204        return tags;
205}
206
207std::set<std::string> Components::getNodeTags()
208{
209        Node *n;
210        std::set<std::string> tags;
211        std::vector<std::string> curTags;
212
213        rewindNodes();
214        while(hasMoreNodes())
215        {
216                n = nextNode();
217                curTags = n->getTags();
218                for(unsigned int count=0; count<curTags.size(); count++)
219                        tags.insert(curTags[count]);
220        }
221        return tags;
222}
223
224
225int Components::getParentWayOfNode(int nodeid)
226{
227        Node *n=getNode(nodeid);
228        if(n)
229        {
230                rewindWays();
231                while(hasMoreWays())
232                {
233                        Way *w=nextWay();
234                        for(int count=0; count<w->nNodes(); count++)
235                        {
236                                if(w->getNode(count)==nodeid)
237                                        return w->id();
238                        }
239                }
240        }
241        return 0;
242}
243
244void Components::toXML(std::ostream &strm)
245{
246        strm << "<?xml version='1.0'?>"<<endl<<"<osm version='0.5'>" << endl;
247        rewindNodes();
248        while(hasMoreNodes())
249        {
250                Node *n=nextNode();
251                n->toXML(strm);
252        }
253        rewindWays();
254        while(hasMoreWays())
255        {
256                Way *w=nextWay();
257                w->toXML(strm);
258        }
259        strm << "</osm>"<<endl;
260}
261
262void Components::toOSGB()
263{
264        rewindNodes();
265        while(hasMoreNodes())
266        {
267                Node *n=nextNode();
268                LatLng latLng (n->getLat(),n->getLon());
269                latLng.toOSGB36();
270                OSRef ref = latLng.toOSRef();
271                n->setCoords(ref.getNorthing(),ref.getEasting());
272        }
273}
274
275
276bool Components::makeShp(const std::string& nodes, const std::string& ways,
277                                                 const std::string& areas,
278                                                 const std::string &featuresFile)
279{
280        std::ifstream in(featuresFile.c_str());
281        if(in.good())
282        {
283                FeatureClassification *featureClassification=FeaturesParser::parse(in);
284                in.close();
285                if (featureClassification && makeNodeShp(nodes))
286                {
287                        if(makeWayShp(ways,featureClassification))
288                        {
289                                if(makeWayShp(areas,featureClassification,true))
290                                {
291                                        return true;
292                                }
293                        }
294                }
295        }
296        return false;
297}
298
299bool Components::makeNodeShp(const std::string& shpname)
300{
301                SHPHandle shp = SHPCreate(shpname.c_str(),SHPT_POINT);
302                if(shp)
303                {
304                        DBFHandle dbf = DBFCreate(shpname.c_str());
305                        if(dbf)
306                        {
307                                std::map<int,std::string> fields;
308                                std::set<std::string> nodeTags = getNodeTags();
309                                for(std::set<std::string>::iterator i=nodeTags.begin();
310                                        i!=nodeTags.end(); i++)
311                                {
312                                        fields[DBFAddField(dbf,i->c_str(),FTString,255,0)] = *i;
313                                }
314
315                                double lon, lat;
316
317                                rewindNodes();
318                                while(hasMoreNodes())
319                                {
320                                        Node *node = nextNode();
321
322                                        // We're only interested in nodes with tags
323                                        if(node && node->hasTags())
324                                        {
325                                                lon = node->getLon();
326                                                lat=node->getLat();
327                                                SHPObject *object = SHPCreateSimpleObject
328                                                        (SHPT_POINT,1,&lon,&lat,NULL);
329
330                                                int objid = SHPWriteObject(shp, -1, object);
331
332                                                SHPDestroyObject(object);
333
334                                                for(std::map<int,std::string>::iterator j=
335                                                                fields.begin(); j!=fields.end(); j++)
336                                                {
337                                                        DBFWriteStringAttribute
338                                                                (dbf,objid,j->first,
339                                                                        node->getTag(j->second).c_str());
340                                                }
341                                        }
342                                }
343
344                                DBFClose(dbf);
345                        }
346                        else
347                        {
348                                cerr << "could not open node dbf" << endl;
349                                return false;
350                        }
351                        SHPClose(shp);
352                }
353                else
354                {
355                        cerr << "could not open node shp" << endl;
356                        return false;
357                }
358
359        return true;
360}
361
362bool Components::makeWayShp(const std::string &shpname,
363                                FeatureClassification *classification, bool doArea)
364{
365                int shpclass = (doArea==true) ? SHPT_POLYGON: SHPT_ARC;
366                // ARC means polyline!
367                SHPHandle shp = SHPCreate(shpname.c_str(),shpclass);
368                if(shp)
369                {
370                        DBFHandle dbf = DBFCreate(shpname.c_str());
371                        if(dbf)
372                        {
373                                std::map<int,std::string> fields;
374                                std::set<std::string> wayTags =
375                                                getWayTags(classification,doArea);
376                                for(std::set<std::string>::iterator i=wayTags.begin();
377                                        i!=wayTags.end(); i++)
378                                {
379                                        fields[DBFAddField(dbf,i->c_str(),FTString,255,0)] = *i;
380                                }
381
382                                std::map<int,Way*>::iterator i=ways.begin();
383                                //rewindWays();
384                                std::vector<double> wayCoords, longs, lats;
385
386                                while(i!=ways.end())
387                                //while(hasMoreWays())
388                                {
389                                        //Way *way = nextWay();
390                                        Way *way= i->second;
391                                        if(way)
392                                        {
393                                                wayCoords = getWayCoords(way->id());
394                                                if(wayCoords.size()
395        && ((doArea==true && classification->getFeatureClass(way)=="area") ||
396                (doArea==false && classification->getFeatureClass(way)!="area"))
397                                                  )
398                                                {
399                                                        longs.clear();
400                                                        lats.clear();
401                                                        for(unsigned int count=0; count<wayCoords.size();count+=2)
402                                                                longs.push_back(wayCoords[count]);
403                                                        for(unsigned int count=1; count<wayCoords.size(); count+=2)
404                                                                lats.push_back(wayCoords[count]);
405
406                                                        SHPObject *object = SHPCreateSimpleObject
407                                                                (shpclass,wayCoords.size()/2,
408                                                                        &(longs[0]),&(lats[0]),NULL);
409
410                                                        int objid = SHPWriteObject(shp, -1, object);
411
412                                                        SHPDestroyObject(object);
413
414                                                        for(std::map<int,std::string>::iterator j=
415                                                                fields.begin(); j!=fields.end(); j++)
416                                                        {
417                                                                DBFWriteStringAttribute
418                                                                (dbf,objid,j->first,
419                                                                        way->getTag(j->second).c_str());
420                                                        }
421                                                }
422                                        }
423                                        i++;
424                                }
425
426                                DBFClose(dbf);
427                        }
428                        else
429                        {
430                                cerr << "could not open way dbf" << endl;
431                                return false;
432                        }
433                        SHPClose(shp);
434                }
435                else
436                {
437                        cerr << "could not open way shp" << endl;
438                        return false;
439                }
440
441        return true;
442}
443
444}
Note: See TracBrowser for help on using the repository browser.