Merge branch 'master' of github.com:mapnik/mapnik into stats_processor

This commit is contained in:
Dane Springmeyer 2012-03-02 10:00:24 -08:00
commit 508f580395
13 changed files with 323 additions and 170 deletions

View file

@ -218,7 +218,7 @@ template <>
inline boost::optional<int> fast_cast(std::string const& value)
{
int result;
if (mapnik::conversions::string2int(value,&result))
if (mapnik::conversions::string2int(value,result))
return boost::optional<int>(result);
return boost::optional<int>();
}
@ -227,7 +227,7 @@ template <>
inline boost::optional<double> fast_cast(std::string const& value)
{
double result;
if (mapnik::conversions::string2double(value,&result))
if (mapnik::conversions::string2double(value,result))
return boost::optional<double>(result);
return boost::optional<double>();
}
@ -236,7 +236,7 @@ template <>
inline boost::optional<float> fast_cast(std::string const& value)
{
float result;
if (mapnik::conversions::string2float(value,&result))
if (mapnik::conversions::string2float(value,result))
return boost::optional<float>(result);
return boost::optional<float>();
}

View file

@ -25,83 +25,19 @@
// mapnik
// boost
#include <boost/spirit/include/qi.hpp>
// stl
#include <string>
namespace mapnik { namespace conversions {
using namespace boost::spirit;
// TODO - convert to templates
static bool string2int(const char * value, int * result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *begin = value;
const char *iter = begin;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,qi::int_,ascii::space,*result);
return r && (iter == end);
}
static bool string2int(std::string const& value, int * result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,qi::int_,ascii::space,*result);
return r && (str_beg == str_end);
}
static bool string2double(std::string const& value, double * result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,qi::double_,ascii::space,*result);
return r && (str_beg == str_end);
}
static bool string2double(const char * value, double * result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *begin = value;
const char *iter = begin;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,qi::double_,ascii::space,*result);
return r && (iter == end);
}
static bool string2float(std::string const& value, float * result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,qi::float_,ascii::space,*result);
return r && (str_beg == str_end);
}
static bool string2float(const char * value, float * result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *begin = value;
const char *iter = begin;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,qi::float_,ascii::space,*result);
return r && (iter == end);
}
bool string2int(const char * value, int & result);
bool string2int(std::string const& value, int & result);
bool string2double(std::string const& value, double & result);
bool string2double(const char * value, double & result);
bool string2float(std::string const& value, float & result);
bool string2float(const char * value, float & result);
}
}

View file

@ -56,91 +56,72 @@ template <typename filterT>
feature_ptr osm_featureset<filterT>::next()
{
feature_ptr feature;
bool success = false;
osm_item* cur_item = dataset_->next_item();
if (cur_item != NULL)
if (!cur_item) return feature_ptr();
if (dataset_->current_item_is_node())
{
if (dataset_->current_item_is_node())
feature = feature_factory::create(ctx_,feature_id_);
++feature_id_;
double lat = static_cast<osm_node*>(cur_item)->lat;
double lon = static_cast<osm_node*>(cur_item)->lon;
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(lon, lat);
feature->add_geometry(point);
}
else if (dataset_->current_item_is_way())
{
// Loop until we find a feature which passes the filter
while (cur_item)
{
bounds b = static_cast<osm_way*>(cur_item)->get_bounds();
if (filter_.pass(box2d<double>(b.w, b.s, b.e, b.n))) break;
cur_item = dataset_->next_item();
}
if (!cur_item) return feature_ptr();
if (static_cast<osm_way*>(cur_item)->nodes.size())
{
feature = feature_factory::create(ctx_,feature_id_);
++feature_id_;
double lat = static_cast<osm_node*>(cur_item)->lat;
double lon = static_cast<osm_node*>(cur_item)->lon;
geometry_type* point = new geometry_type(mapnik::Point);
point->move_to(lon, lat);
feature->add_geometry(point);
success = true;
}
else if (dataset_->current_item_is_way())
{
bounds b = static_cast<osm_way*>(cur_item)->get_bounds();
// Loop until we find a feature which passes the filter
while (cur_item != NULL &&
! filter_.pass(box2d<double>(b.w, b.s, b.e, b.n)))
geometry_type* geom;
if (static_cast<osm_way*>(cur_item)->is_polygon())
{
cur_item = dataset_->next_item();
if (cur_item != NULL)
{
b = static_cast<osm_way*>(cur_item)->get_bounds();
}
geom = new geometry_type(mapnik::Polygon);
}
else
{
geom = new geometry_type(mapnik::LineString);
}
if (cur_item != NULL)
geom->move_to(static_cast<osm_way*>(cur_item)->nodes[0]->lon,
static_cast<osm_way*>(cur_item)->nodes[0]->lat);
for (unsigned int count = 1;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
if (static_cast<osm_way*>(cur_item)->nodes.size())
{
feature = feature_factory::create(ctx_,feature_id_);
++feature_id_;
geometry_type* geom;
if (static_cast<osm_way*>(cur_item)->is_polygon())
{
geom = new geometry_type(mapnik::Polygon);
}
else
{
geom = new geometry_type(mapnik::LineString);
}
geom->move_to(static_cast<osm_way*>(cur_item)->nodes[0]->lon,
static_cast<osm_way*>(cur_item)->nodes[0]->lat);
for (unsigned int count = 1;
count < static_cast<osm_way*>(cur_item)->nodes.size();
count++)
{
geom->line_to(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
feature->add_geometry(geom);
success = true;
}
geom->line_to(static_cast<osm_way*>(cur_item)->nodes[count]->lon,
static_cast<osm_way*>(cur_item)->nodes[count]->lat);
}
}
// can feature_ptr be compared to NULL? - no
if (success)
{
std::map<std::string,std::string>::iterator i = cur_item->keyvals.begin();
// add the keyvals to the feature. the feature seems to be a map
// of some sort so this should work - see dbf_file::add_attribute()
while (i != cur_item->keyvals.end())
{
// only add if in the specified set of attribute names
if (attribute_names_.find(i->first) != attribute_names_.end())
{
feature->put(i->first,tr_->transcode(i->second.c_str()));
}
i++;
}
return feature;
feature->add_geometry(geom);
}
}
return feature_ptr();
std::set<std::string>::const_iterator itr = attribute_names_.begin();
std::set<std::string>::const_iterator end = attribute_names_.end();
std::map<std::string,std::string>::iterator end_keyvals = cur_item->keyvals.end();
for (; itr != end; itr++)
{
std::map<std::string,std::string>::iterator i = cur_item->keyvals.find(*itr);
if (i != end_keyvals) {
feature->put_new(i->first,tr_->transcode(i->second.c_str()));
} else {
feature->put_new(*itr, "");
}
}
return feature;
}
template <typename filterT>

View file

@ -50,8 +50,6 @@ public:
conn_ = PQconnectdb(connection_str.c_str());
if (PQstatus(conn_) != CONNECTION_OK)
{
// note: empty ctor is intentional here
// as somehow constructor string can dissapear
std::ostringstream s;
s << "Postgis Plugin: ";
if (conn_ )

View file

@ -175,7 +175,7 @@ void postgis_datasource::bind() const
if (srid_c != NULL)
{
int result;
if (mapnik::conversions::string2int(srid_c,&result))
if (mapnik::conversions::string2int(srid_c,result))
srid_ = result;
}
}
@ -205,7 +205,7 @@ void postgis_datasource::bind() const
if (srid_c != NULL)
{
int result;
if (mapnik::conversions::string2int(srid_c,&result))
if (mapnik::conversions::string2int(srid_c,result))
srid_ = result;
}
}
@ -685,10 +685,10 @@ box2d<double> postgis_datasource::envelope() const
double loy;
double hix;
double hiy;
if (mapnik::conversions::string2double(rs->getValue(0),&lox) &&
mapnik::conversions::string2double(rs->getValue(1),&loy) &&
mapnik::conversions::string2double(rs->getValue(2),&hix) &&
mapnik::conversions::string2double(rs->getValue(3),&hiy))
if (mapnik::conversions::string2double(rs->getValue(0),lox) &&
mapnik::conversions::string2double(rs->getValue(1),loy) &&
mapnik::conversions::string2double(rs->getValue(2),hix) &&
mapnik::conversions::string2double(rs->getValue(3),hiy))
{
extent_.init(lox,loy,hix,hiy);
extent_initialized_ = true;

View file

@ -162,7 +162,7 @@ feature_ptr postgis_featureset::next()
{
std::string str = mapnik::sql_utils::numeric2string(buf);
double val;
if (mapnik::conversions::string2double(str,&val))
if (mapnik::conversions::string2double(str,val))
feature->put(name,val);
}
else

View file

@ -104,6 +104,7 @@ else: # Linux and others
source = Split(
"""
color.cpp
conversions.cpp
box2d.cpp
building_symbolizer.cpp
datasource_cache.cpp

106
src/conversions.cpp Normal file
View file

@ -0,0 +1,106 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 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
*
*****************************************************************************/
// boost
#include <boost/spirit/include/qi.hpp>
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
typedef boost::proto::result_of:: \
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
BOOST_SPIRIT_ASSERT_MATCH( \
boost::spirit::domain_::domain, name##_expr_type); \
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
namespace mapnik { namespace conversions {
using namespace boost::spirit;
BOOST_SPIRIT_AUTO(qi, INTEGER, qi::int_);
BOOST_SPIRIT_AUTO(qi, FLOAT, qi::float_);
BOOST_SPIRIT_AUTO(qi, DOUBLE, qi::double_);
bool string2int(const char * value, int & result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *iter = value;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,INTEGER,ascii::space,result);
return r && (iter == end);
}
bool string2int(std::string const& value, int & result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,INTEGER,ascii::space,result);
return r && (str_beg == str_end);
}
bool string2double(std::string const& value, double & result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,DOUBLE,ascii::space,result);
return r && (str_beg == str_end);
}
bool string2double(const char * value, double & result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *iter = value;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,DOUBLE,ascii::space,result);
return r && (iter == end);
}
bool string2float(std::string const& value, float & result)
{
if (value.empty())
return false;
std::string::const_iterator str_beg = value.begin();
std::string::const_iterator str_end = value.end();
bool r = qi::phrase_parse(str_beg,str_end,FLOAT,ascii::space,result);
return r && (str_beg == str_end);
}
bool string2float(const char * value, float & result)
{
size_t length = strlen(value);
if (length < 1 || value == NULL)
return false;
const char *iter = value;
const char *end = value + length;
bool r = qi::phrase_parse(iter,end,FLOAT,ascii::space,result);
return r && (iter == end);
}
}
}

View file

@ -158,7 +158,7 @@ void handle_png_options(std::string const& type,
if (*colors < 0)
throw ImageWriterException("invalid color parameter: unavailable for true color images");
if (!mapnik::conversions::string2int(t.substr(2),colors) || *colors < 0 || *colors > 256)
if (!mapnik::conversions::string2int(t.substr(2),*colors) || *colors < 0 || *colors > 256)
throw ImageWriterException("invalid color parameter: " + t.substr(2));
}
else if (boost::algorithm::starts_with(t, "t="))
@ -166,14 +166,14 @@ void handle_png_options(std::string const& type,
if (*colors < 0)
throw ImageWriterException("invalid trans_mode parameter: unavailable for true color images");
if (!mapnik::conversions::string2int(t.substr(2),trans_mode) || *trans_mode < 0 || *trans_mode > 2)
if (!mapnik::conversions::string2int(t.substr(2),*trans_mode) || *trans_mode < 0 || *trans_mode > 2)
throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2));
}
else if (boost::algorithm::starts_with(t, "g="))
{
if (*colors < 0)
throw ImageWriterException("invalid gamma parameter: unavailable for true color images");
if (!mapnik::conversions::string2double(t.substr(2),gamma) || *gamma < 0)
if (!mapnik::conversions::string2double(t.substr(2),*gamma) || *gamma < 0)
{
throw ImageWriterException("invalid gamma parameter: " + t.substr(2));
}
@ -186,7 +186,7 @@ void handle_png_options(std::string const& type,
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)
*/
if (!mapnik::conversions::string2int(t.substr(2),compression)
if (!mapnik::conversions::string2int(t.substr(2),*compression)
|| *compression < Z_DEFAULT_COMPRESSION
|| *compression > Z_BEST_COMPRESSION)
{
@ -317,7 +317,7 @@ void save_to_stream(T const& image,
std::string const& val = t.substr(4);
if (!val.empty())
{
if (!mapnik::conversions::string2int(val,&quality) || quality < 0 || quality > 100)
if (!mapnik::conversions::string2int(val,quality) || quality < 0 || quality > 100)
{
throw ImageWriterException("invalid jpeg quality: '" + val + "'");
}

View file

@ -62,7 +62,10 @@ text_placement_info_ptr text_symbolizer_helper<FaceManagerT, DetectorT>::get_lin
if (!placement_->placements.empty())
{
//Found a placement
finder.update_detector();
if (points_on_line_)
{
finder.update_detector();
}
geo_itr_ = geometries_to_process_.erase(geo_itr_);
if (writer_.first) writer_.first->add_text(
*placement_, font_manager_,

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Map>
<Map background-color="white" srs="+proj=latlong +datum=WGS84">
<Layer name="layer" srs="+proj=latlong +datum=WGS84">
<StyleName>My Style</StyleName>
<Datasource>
<Parameter name="type">osm</Parameter>
<Parameter name="file">lines.osm</Parameter>
</Datasource>
</Layer>
<Style name="My Style">
<Rule>
<LineSymbolizer/>
<TextSymbolizer face-name="DejaVu Sans Book" size="16" placement="line">[name]</TextSymbolizer>
</Rule>
</Style>
</Map>

View file

@ -0,0 +1,101 @@
<?xml version='1.0' encoding='UTF-8'?>
<osm version='0.6' upload='true' generator='JOSM'>
<node id='-261' action='modify' visible='true' lat='-0.1332891529545811' lon='0.1504154935636508' />
<node id='-260' action='modify' visible='true' lat='-0.1757169043083409' lon='0.1305231545125279' />
<node id='-259' action='modify' visible='true' lat='-0.21978370904872907' lon='0.1464582071314902' />
<node id='-258' action='modify' visible='true' lat='-0.2396758881013458' lon='0.18888611371347797' />
<node id='-257' action='modify' visible='true' lat='-0.2237409658387897' lon='0.23295318200586176' />
<node id='-256' action='modify' visible='true' lat='-0.18131332528509406' lon='0.25284552105698477' />
<node id='-255' action='modify' visible='true' lat='-0.13724642835761083' lon='0.23691046843802263' />
<node id='-254' action='modify' visible='true' lat='-0.11735413850500562' lon='0.1944825618560347' />
<node id='-241' action='modify' visible='true' lat='-0.1655217334959332' lon='0.6833758097485068' />
<node id='-240' action='modify' visible='true' lat='-0.2095885646018953' lon='0.6993108623674691' />
<node id='-239' action='modify' visible='true' lat='-0.22948075753179561' lon='0.7417387689494566' />
<node id='-238' action='modify' visible='true' lat='-0.17111815748676526' lon='0.8056981762929635' />
<node id='-237' action='modify' visible='true' lat='-0.12705123945853983' lon='0.7897631236740015' />
<node id='-236' action='modify' visible='true' lat='-0.10715894205645898' lon='0.7473352170920137' />
<node id='-213' action='modify' visible='true' lat='-0.21354582405473055' lon='0.7858058372418406' />
<node id='-212' action='modify' visible='true' lat='-0.12309396245573988' lon='0.7032681487996296' />
<node id='-162' action='modify' visible='true' lat='-0.24021531354004155' lon='0.5353063117093004' />
<node id='-161' action='modify' visible='true' lat='-0.24021531354004155' lon='0.3464872162319133' />
<node id='-92' action='modify' visible='true' lat='-0.12211234158461091' lon='0.5358780838867709' />
<node id='-91' action='modify' visible='true' lat='-0.12211234158461091' lon='0.34705898840938354' />
<node id='-73' action='modify' visible='true' lat='-0.01764759069089235' lon='0.9034048508876044' />
<node id='-72' action='modify' visible='true' lat='-0.01764759069089235' lon='0.003404850887603978' />
<node id='-53' action='modify' visible='true' lat='0.07317849201080144' lon='0.9022677520769676' />
<node id='-52' action='modify' visible='true' lat='0.07317849201080144' lon='0.0022677520769677586' />
<node id='-22' action='modify' visible='true' lat='0.17252937235850266' lon='0.9034112964319083' />
<node id='-20' action='modify' visible='true' lat='0.17252937235851112' lon='0.8034112964319083' />
<node id='-18' action='modify' visible='true' lat='0.17252937235851112' lon='0.7034112964319083' />
<node id='-16' action='modify' visible='true' lat='0.17252937235851112' lon='0.6034112964319084' />
<node id='-14' action='modify' visible='true' lat='0.17252937235851112' lon='0.5034112964319082' />
<node id='-12' action='modify' visible='true' lat='0.17252937235851112' lon='0.40341129643190826' />
<node id='-10' action='modify' visible='true' lat='0.17252937235851112' lon='0.30341129643190823' />
<node id='-8' action='modify' visible='true' lat='0.17252937235851112' lon='0.20341129643190828' />
<node id='-6' action='modify' visible='true' lat='0.17252937235851112' lon='0.10341129643190829' />
<node id='-4' action='modify' visible='true' lat='0.17252937235850266' lon='0.0034112964319082647' />
<way id='-253' action='modify' visible='true'>
<nd ref='-254' />
<nd ref='-255' />
<nd ref='-256' />
<nd ref='-257' />
<nd ref='-258' />
<nd ref='-259' />
<nd ref='-260' />
<nd ref='-261' />
<nd ref='-254' />
<tag k='name' v='Circle' />
<tag k='nr' v='6' />
</way>
<way id='-214' action='modify' visible='true'>
<nd ref='-236' />
<nd ref='-237' />
<nd ref='-238' />
<nd ref='-213' />
<nd ref='-239' />
<nd ref='-240' />
<nd ref='-241' />
<nd ref='-212' />
<nd ref='-236' />
<tag k='name' v='Circle with long name' />
<tag k='nr' v='7' />
</way>
<way id='-160' action='modify' visible='true'>
<nd ref='-161' />
<nd ref='-162' />
<tag k='name' v='Short line with long name' />
<tag k='nr' v='5' />
</way>
<way id='-90' action='modify' visible='true'>
<nd ref='-91' />
<nd ref='-92' />
<tag k='name' v='Short line' />
<tag k='nr' v='4' />
</way>
<way id='-71' action='modify' visible='true'>
<nd ref='-72' />
<nd ref='-73' />
<tag k='name' v='Short name' />
<tag k='nr' v='3' />
</way>
<way id='-51' action='modify' visible='true'>
<nd ref='-52' />
<nd ref='-53' />
<tag k='name' v='Long line with long name' />
<tag k='nr' v='2' />
</way>
<way id='-25' action='modify' visible='true'>
<nd ref='-4' />
<nd ref='-6' />
<nd ref='-8' />
<nd ref='-10' />
<nd ref='-12' />
<nd ref='-14' />
<nd ref='-16' />
<nd ref='-18' />
<nd ref='-20' />
<nd ref='-22' />
<tag k='name' v='Long line with long name and many points' />
<tag k='nr' v='1' />
</way>
</osm>

View file

@ -11,6 +11,7 @@ dirname = os.path.dirname(sys.argv[0])
files = [
("list", 800, 600, 400, 300, 250, 200, 150, 100),
("simple", 800, 600, 400, 300, 250, 200, 150, 100),
("lines-1", (800, 800), (600, 600), (400, 400), (200, 200)),
("simple-E", 500),
("simple-NE", 500),
("simple-NW", 500),
@ -26,21 +27,24 @@ files = [
("shieldsymbolizer-1", 490, 495, 497, 498, 499, 500, 501, 502, 505, 510),
("expressionformat", 500)]
def render(filename, width):
def render(filename, width, height=100):
print "-"*80
print "Rendering style \"%s\" with size %dx%d ... " % (filename, width, height)
print "-"*80
width = int(width)
m = mapnik.Map(width, 100)
height = int(height)
m = mapnik.Map(width, height)
mapnik.load_map(m, os.path.join(dirname, "%s.xml" % filename), False)
bbox = mapnik.Box2d(-0.05, -0.01, 0.95, 0.01)
m.zoom_to_box(bbox)
basefn = '%s-%d' % (filename, width)
mapnik.render_to_file(m, basefn+'-agg.png')
diff = compare(basefn + '-agg.png', basefn + '-reference.png')
if diff == 0:
rms = 'ok'
else:
rms = 'error: %u different pixels' % diff
if diff > 0:
print "-"*80
print 'Error: %u different pixels' % diff
print "-"*80
print "Rendering style \"%s\" with width %d ... %s" % (filename, width, rms)
return m
if len(sys.argv) == 2:
@ -50,7 +54,10 @@ elif len(sys.argv) > 2:
for f in files:
for width in f[1:]:
m = render(f[0], width)
if isinstance(width, tuple):
m = render(f[0], width[0], width[1])
else:
m = render(f[0], width)
mapnik.save_map(m, "%s-out.xml" % f[0])
summary()