2011-10-22 16:04:05 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
*
|
|
|
|
* This file is part of Mapnik (c++ mapping toolkit)
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Artem Pavlenko
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*
|
|
|
|
*****************************************************************************/
|
|
|
|
|
2008-03-01 12:49:37 +01:00
|
|
|
#include "osm.h"
|
2008-03-02 14:23:50 +01:00
|
|
|
#include "osmparser.h"
|
2011-10-22 16:04:05 +02:00
|
|
|
#include "basiccurl.h"
|
|
|
|
|
2008-03-01 12:49:37 +01:00
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <string>
|
|
|
|
|
2008-04-02 23:40:28 +02:00
|
|
|
polygon_types osm_way::ptypes;
|
|
|
|
|
2008-03-01 12:49:37 +01:00
|
|
|
bool osm_dataset::load(const char* filename,const std::string& parser)
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (parser == "libxml2")
|
|
|
|
{
|
|
|
|
return osmparser::parse(this, filename);
|
|
|
|
}
|
|
|
|
return false;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
2009-02-15 14:51:07 +01:00
|
|
|
bool osm_dataset::load_from_url(const std::string& url,
|
2011-10-22 16:04:05 +02:00
|
|
|
const std::string& bbox,
|
|
|
|
const std::string& parser)
|
2009-02-15 14:51:07 +01:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (parser == "libxml2")
|
|
|
|
{
|
2009-04-28 22:07:18 +02:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: osm_dataset::load_from_url url=" << url << " bbox=" << bbox << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
2011-10-22 16:04:05 +02:00
|
|
|
|
|
|
|
std::ostringstream str;
|
|
|
|
// use curl to grab the data
|
|
|
|
// fetch all the data we want - probably from osmxpai
|
2009-02-15 14:51:07 +01:00
|
|
|
|
|
|
|
str << url << "?bbox=" << bbox;
|
2009-04-28 22:07:18 +02:00
|
|
|
|
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: FULL URL " << str.str() << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
CURL_LOAD_DATA* resp = grab_http_response(str.str().c_str());
|
|
|
|
|
|
|
|
if (resp != NULL)
|
|
|
|
{
|
|
|
|
char *blx = new char[resp->nbytes + 1];
|
|
|
|
memcpy(blx, resp->data, resp->nbytes);
|
|
|
|
blx[resp->nbytes] = '\0';
|
2009-04-28 22:07:18 +02:00
|
|
|
|
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: CURL RESPONSE: " << blx << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
delete[] blx;
|
|
|
|
bool success = osmparser::parse(this, resp->data, resp->nbytes);
|
|
|
|
return success;
|
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
return false;
|
2009-02-15 14:51:07 +01:00
|
|
|
}
|
|
|
|
|
2008-03-01 12:49:37 +01:00
|
|
|
osm_dataset::~osm_dataset()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
clear();
|
2009-02-17 00:10:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void osm_dataset::clear()
|
|
|
|
{
|
2009-04-28 22:07:18 +02:00
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: osm_dataset::clear()" << std::endl;
|
|
|
|
std::clog << "Osm Plugin: deleting ways" << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
for (unsigned int count = 0; count < ways.size(); ++count)
|
|
|
|
{
|
|
|
|
delete ways[count];
|
|
|
|
ways[count] = NULL;
|
|
|
|
}
|
2009-04-28 22:07:18 +02:00
|
|
|
|
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: deleting nodes" << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
|
|
|
{
|
|
|
|
delete nodes[count];
|
|
|
|
nodes[count] = NULL;
|
|
|
|
}
|
2009-04-28 22:07:18 +02:00
|
|
|
|
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: clearing ways/nodes" << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
ways.clear();
|
|
|
|
nodes.clear();
|
2009-04-28 22:07:18 +02:00
|
|
|
|
|
|
|
#ifdef MAPNIK_DEBUG
|
2011-10-22 16:04:05 +02:00
|
|
|
std::clog << "Osm Plugin: done" << std::endl;
|
2009-04-28 22:07:18 +02:00
|
|
|
#endif
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string osm_dataset::to_string()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
std::string result;
|
|
|
|
|
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
|
|
|
{
|
|
|
|
result += nodes[count]->to_string();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (unsigned int count = 0; count < ways.size(); ++count)
|
|
|
|
{
|
|
|
|
result += ways[count]->to_string();
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bounds osm_dataset::get_bounds()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
bounds b (-180, -90, 180, 90);
|
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
|
|
|
{
|
|
|
|
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
|
|
|
|
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
|
|
|
|
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
|
|
|
|
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
|
|
|
|
}
|
|
|
|
return b;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
osm_node* osm_dataset::next_node()
|
2008-03-01 12:49:37 +01:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (node_i != nodes.end())
|
|
|
|
{
|
|
|
|
return *(node_i++);
|
|
|
|
}
|
|
|
|
return NULL;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
|
|
|
|
osm_way* osm_dataset::next_way()
|
2008-03-01 12:49:37 +01:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (way_i != ways.end())
|
|
|
|
{
|
|
|
|
return *(way_i++);
|
|
|
|
}
|
|
|
|
return NULL;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
osm_item* osm_dataset::next_item()
|
2008-03-01 12:49:37 +01:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
osm_item* item = NULL;
|
|
|
|
if (next_item_mode == Node)
|
|
|
|
{
|
|
|
|
item = next_node();
|
|
|
|
if (item == NULL)
|
|
|
|
{
|
|
|
|
next_item_mode = Way;
|
|
|
|
rewind_ways();
|
|
|
|
item = next_way();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2011-04-02 05:45:50 +02:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
item = next_way();
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
return item;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
|
2008-03-01 12:49:37 +01:00
|
|
|
std::set<std::string> osm_dataset::get_keys()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
std::set<std::string> keys;
|
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
2011-04-02 05:45:50 +02:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
for (std::map<std::string, std::string>::iterator i = nodes[count]->keyvals.begin();
|
|
|
|
i != nodes[count]->keyvals.end(); i++)
|
|
|
|
{
|
|
|
|
keys.insert(i->first);
|
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
|
|
|
|
for (unsigned int count = 0; count < ways.size(); ++count)
|
2011-04-02 05:45:50 +02:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
for (std::map<std::string, std::string>::iterator i = ways[count]->keyvals.begin();
|
|
|
|
i != ways[count]->keyvals.end(); i++)
|
|
|
|
{
|
|
|
|
keys.insert(i->first);
|
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
return keys;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string osm_item::to_string()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
std::ostringstream strm;
|
|
|
|
strm << "id=" << id << std::endl << "Keyvals: " << std::endl;
|
|
|
|
|
|
|
|
for (std::map<std::string, std::string>::iterator i = keyvals.begin();
|
|
|
|
i != keyvals.end(); i++)
|
|
|
|
{
|
|
|
|
strm << "Key " << i->first << " Value " << i->second << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
return strm.str();
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string osm_node::to_string()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
std::ostringstream strm;
|
|
|
|
strm << "Node: " << osm_item::to_string() << " lat=" << lat <<" lon=" <<lon << std::endl;
|
|
|
|
return strm.str();
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string osm_way::to_string()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
std::ostringstream strm;
|
|
|
|
strm << "Way: " << osm_item::to_string() << "Nodes in way:";
|
2008-03-01 12:49:37 +01:00
|
|
|
|
2011-10-22 16:04:05 +02:00
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
2011-04-02 05:45:50 +02:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (nodes[count] != NULL)
|
|
|
|
{
|
|
|
|
strm << nodes[count]->id << " ";
|
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
|
|
|
|
strm << std::endl;
|
|
|
|
return strm.str();
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bounds osm_way::get_bounds()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
bounds b (-180, -90, 180, 90);
|
|
|
|
|
|
|
|
for (unsigned int count = 0; count < nodes.size(); ++count)
|
|
|
|
{
|
|
|
|
if(nodes[count]->lon > b.w) b.w = nodes[count]->lon;
|
|
|
|
if(nodes[count]->lon < b.e) b.e = nodes[count]->lon;
|
|
|
|
if(nodes[count]->lat > b.s) b.s = nodes[count]->lat;
|
|
|
|
if(nodes[count]->lat < b.n) b.n = nodes[count]->lat;
|
|
|
|
}
|
|
|
|
return b;
|
2008-03-01 12:49:37 +01:00
|
|
|
}
|
2008-04-02 23:40:28 +02:00
|
|
|
|
|
|
|
bool osm_way::is_polygon()
|
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
for (unsigned int count = 0; count < ptypes.ptypes.size(); ++count)
|
2011-04-02 05:45:50 +02:00
|
|
|
{
|
2011-10-22 16:04:05 +02:00
|
|
|
if (keyvals.find(ptypes.ptypes[count].first) != keyvals.end() &&
|
|
|
|
keyvals[ptypes.ptypes[count].first] == ptypes.ptypes[count].second)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
2011-04-02 05:45:50 +02:00
|
|
|
}
|
2011-10-22 16:04:05 +02:00
|
|
|
|
|
|
|
return false;
|
2008-04-02 23:40:28 +02:00
|
|
|
}
|