From b5c4bb77de1f48312d64387d5118711ac0b2eea2 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Wed, 12 Oct 2011 01:05:35 +0100 Subject: [PATCH 01/33] Exposed the label collision detector outside the agg_render object and via Python, allowing detectors to be re-used across renderings. --- bindings/python/mapnik_python.cpp | 38 +++++++++++++++++++++ include/mapnik/agg_renderer.hpp | 9 ++++- include/mapnik/label_collision_detector.hpp | 10 ++++-- src/agg/agg_renderer.cpp | 27 +++++++++++++-- src/agg/process_glyph_symbolizer.cpp | 6 ++-- src/agg/process_markers_symbolizer.cpp | 8 ++--- src/agg/process_point_symbolizer.cpp | 4 +-- src/agg/process_shield_symbolizer.cpp | 6 ++-- src/agg/process_text_symbolizer.cpp | 2 +- 9 files changed, 92 insertions(+), 18 deletions(-) diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index 9d36aebc6..03c6fc75f 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -66,6 +66,7 @@ void export_view_transform(); void export_raster_colorizer(); void export_glyph_symbolizer(); void export_inmem_metawriter(); +void export_label_collision_detector(); #include #include @@ -120,6 +121,28 @@ void render(const mapnik::Map& map, Py_END_ALLOW_THREADS } +void render_with_detector( + const mapnik::Map &map, + mapnik::image_32 &image, + boost::shared_ptr detector, + double scale_factor = 1.0, + unsigned offset_x = 0u, + unsigned offset_y = 0u) +{ + Py_BEGIN_ALLOW_THREADS + try + { + mapnik::agg_renderer ren(map,image,detector); + ren.apply(); + } + catch (...) + { + Py_BLOCK_THREADS + throw; + } + Py_END_ALLOW_THREADS +} + void render_layer2(const mapnik::Map& map, mapnik::image_32& image, unsigned layer_idx) @@ -374,6 +397,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(load_map_string_overloads, load_map_string, 2, 4 BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_overloads, save_map, 2, 3) BOOST_PYTHON_FUNCTION_OVERLOADS(save_map_to_string_overloads, save_map_to_string, 1, 2) BOOST_PYTHON_FUNCTION_OVERLOADS(render_overloads, render, 2, 5) +BOOST_PYTHON_FUNCTION_OVERLOADS(render_with_detector_overloads, render_with_detector, 3, 6) BOOST_PYTHON_MODULE(_mapnik2) { @@ -427,6 +451,7 @@ BOOST_PYTHON_MODULE(_mapnik2) export_raster_colorizer(); export_glyph_symbolizer(); export_inmem_metawriter(); + export_label_collision_detector(); def("render_grid",&render_grid, ( arg("map"), @@ -503,6 +528,19 @@ BOOST_PYTHON_MODULE(_mapnik2) "\n" )); + def("render_with_detector", &render_with_detector, render_with_detector_overloads( + "\n" + "Render Map to an AGG image_32 using a pre-constructed detector.\n" + "\n" + "Usage:\n" + ">>> from mapnik import Map, Image, LabelCollisionDetector, render_with_detector, load_map\n" + ">>> m = Map(256,256)\n" + ">>> load_map(m,'mapfile.xml')\n" + ">>> im = Image(m.width,m.height)\n" + ">>> detector = LabelCollisionDetector(m)\n" + ">>> render_with_detector(m, im, detector)\n" + )); + def("render_layer", &render_layer2, (arg("map"),arg("image"),args("layer")) ); diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 08a48d44a..3e5e218a5 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -40,6 +40,7 @@ // boost #include #include +#include // FIXME // forward declare so that @@ -61,7 +62,11 @@ class MAPNIK_DECL agg_renderer : public feature_style_processor { public: + // create with default, empty placement detector agg_renderer(Map const& m, T & pixmap, double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); + // create with external placement detector, possibly non-empty + agg_renderer(Map const &m, T & pixmap, boost::shared_ptr detector, + double scale_factor=1.0, unsigned offset_x=0, unsigned offset_y=0); ~agg_renderer(); void start_map_processing(Map const& map); void end_map_processing(Map const& map); @@ -122,8 +127,10 @@ private: CoordTransform t_; freetype_engine font_engine_; face_manager font_manager_; - label_collision_detector4 detector_; + boost::shared_ptr detector_; boost::scoped_ptr ras_ptr; + + void setup(Map const &m); }; } diff --git a/include/mapnik/label_collision_detector.hpp b/include/mapnik/label_collision_detector.hpp index f52d394e1..b9da67595 100644 --- a/include/mapnik/label_collision_detector.hpp +++ b/include/mapnik/label_collision_detector.hpp @@ -69,7 +69,7 @@ class label_collision_detector2 : boost::noncopyable typedef quad_tree > tree_t; tree_t tree_; public: - + explicit label_collision_detector2(box2d const& extent) : tree_(extent) {} @@ -138,6 +138,7 @@ public: //quad tree based label collission detector so labels dont appear within a given distance class label_collision_detector4 : boost::noncopyable { +public: struct label { label(box2d const& b) : box(b) {} @@ -146,11 +147,13 @@ class label_collision_detector4 : boost::noncopyable box2d box; UnicodeString text; }; - + +private: typedef quad_tree< label > tree_t; tree_t tree_; public: + typedef tree_t::query_iterator query_iterator; explicit label_collision_detector4(box2d const& extent) : tree_(extent) {} @@ -224,6 +227,9 @@ public: { return tree_.extent(); } + + query_iterator begin() { return tree_.query_in_box(extent()); } + query_iterator end() { return tree_.query_end(); } }; } diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index 42793cf49..bcdc8ef12 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -121,8 +121,31 @@ agg_renderer::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), font_engine_(), font_manager_(font_engine_), - detector_(box2d(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size())), + detector_(new label_collision_detector4(box2d(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))), ras_ptr(new rasterizer) +{ + setup(m); +} + +template +agg_renderer::agg_renderer(Map const& m, T & pixmap, boost::shared_ptr detector, + double scale_factor, unsigned offset_x, unsigned offset_y) + : feature_style_processor(m, scale_factor), + pixmap_(pixmap), + width_(pixmap_.width()), + height_(pixmap_.height()), + scale_factor_(scale_factor), + t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), + font_engine_(), + font_manager_(font_engine_), + detector_(detector), + ras_ptr(new rasterizer) +{ + setup(m); +} + +template +void agg_renderer::setup(Map const &m) { boost::optional const& bg = m.background(); if (bg) pixmap_.set_background(*bg); @@ -189,7 +212,7 @@ void agg_renderer::start_layer_processing(layer const& lay) #endif if (lay.clear_label_cache()) { - detector_.clear(); + detector_->clear(); } } diff --git a/src/agg/process_glyph_symbolizer.cpp b/src/agg/process_glyph_symbolizer.cpp index e3b31b3cb..674c2eed7 100644 --- a/src/agg/process_glyph_symbolizer.cpp +++ b/src/agg/process_glyph_symbolizer.cpp @@ -77,12 +77,12 @@ void agg_renderer::process(glyph_symbolizer const& sym, // final box so we can check for a valid placement box2d dim = ren.prepare_glyphs(path.get()); box2d ext(x-dim.width()/2, y-dim.height()/2, x+dim.width()/2, y+dim.height()/2); - if ((sym.get_allow_overlap() || detector_.has_placement(ext)) && - (!sym.get_avoid_edges() || detector_.extent().contains(ext))) + if ((sym.get_allow_overlap() || detector_->has_placement(ext)) && + (!sym.get_avoid_edges() || detector_->extent().contains(ext))) { // Placement is valid, render glyph and update detector. ren.render(x, y); - detector_.insert(ext); + detector_->insert(ext); metawriter_with_properties writer = sym.get_metawriter(); if (writer.first) writer.first->add_box(ext, feature, t_, writer.second); } diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index d40b02ee7..cd9757a01 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -109,7 +109,7 @@ void agg_renderer::process(markers_symbolizer const& sym, } path_type path(t_,geom,prj_trans); - markers_placement placement(path, extent, detector_, + markers_placement placement(path, extent, *detector_, sym.get_spacing() * scale_factor_, sym.get_max_error(), sym.get_allow_overlap()); @@ -194,7 +194,7 @@ void agg_renderer::process(markers_symbolizer const& sym, box2d label_ext (px, py, px + dx +1, py + dy +1); if (sym.get_allow_overlap() || - detector_.has_placement(label_ext)) + detector_->has_placement(label_ext)) { agg::ellipse c(x, y, w, h); marker.concat_path(c); @@ -215,7 +215,7 @@ void agg_renderer::process(markers_symbolizer const& sym, ren.color(agg::rgba8(s_r, s_g, s_b, int(s_a*stroke_.get_opacity()))); agg::render_scanlines(*ras_ptr, sl_line, ren); } - detector_.insert(label_ext); + detector_->insert(label_ext); if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second); } } @@ -226,7 +226,7 @@ void agg_renderer::process(markers_symbolizer const& sym, marker.concat_path(arrow_); path_type path(t_,geom,prj_trans); - markers_placement placement(path, extent, detector_, + markers_placement placement(path, extent, *detector_, sym.get_spacing() * scale_factor_, sym.get_max_error(), sym.get_allow_overlap()); diff --git a/src/agg/process_point_symbolizer.cpp b/src/agg/process_point_symbolizer.cpp index fd57ec1d5..d9974d82e 100644 --- a/src/agg/process_point_symbolizer.cpp +++ b/src/agg/process_point_symbolizer.cpp @@ -99,13 +99,13 @@ void agg_renderer::process(point_symbolizer const& sym, label_ext.re_center(x,y); if (sym.get_allow_overlap() || - detector_.has_placement(label_ext)) + detector_->has_placement(label_ext)) { render_marker(floor(x - 0.5 * w),floor(y - 0.5 * h) ,**marker,tr, sym.get_opacity()); if (!sym.get_ignore_placement()) - detector_.insert(label_ext); + detector_->insert(label_ext); metawriter_with_properties writer = sym.get_metawriter(); if (writer.first) writer.first->add_box(label_ext, feature, t_, writer.second); } diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index cb3591abc..17f87e0e0 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -135,7 +135,7 @@ void agg_renderer::process(shield_symbolizer const& sym, ren.set_halo_radius(sym.get_halo_radius() * scale_factor_); ren.set_opacity(sym.get_text_opacity()); - placement_finder finder(detector_); + placement_finder finder(*detector_); string_info info(text); @@ -210,13 +210,13 @@ void agg_renderer::process(shield_symbolizer const& sym, label_ext.re_center(label_x,label_y); } - if ( sym.get_allow_overlap() || detector_.has_placement(label_ext) ) + if ( sym.get_allow_overlap() || detector_->has_placement(label_ext) ) { render_marker(px,py,**marker,tr,sym.get_opacity()); box2d dim = ren.prepare_glyphs(&text_placement.placements[0]); ren.render(x,y); - detector_.insert(label_ext); + detector_->insert(label_ext); finder.update_detector(text_placement); if (writer.first) { writer.first->add_box(label_ext, feature, t_, writer.second); diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index 58b00a4d6..3d7440c19 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -110,7 +110,7 @@ void agg_renderer::process(text_symbolizer const& sym, ren.set_opacity(sym.get_text_opacity()); box2d dims(0,0,width_,height_); - placement_finder finder(detector_,dims); + placement_finder finder(*detector_,dims); string_info info(text); From d29f60905256e50c835ba4ce2ce6dd857a4681d0 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Wed, 12 Oct 2011 01:08:03 +0100 Subject: [PATCH 02/33] Added a 'multi' tiled raster plugin reader for virtual images already present as tiles on disk. --- plugins/input/raster/raster_datasource.cpp | 76 ++++++++---- plugins/input/raster/raster_datasource.hpp | 3 + plugins/input/raster/raster_featureset.cpp | 25 +++- plugins/input/raster/raster_featureset.hpp | 131 ++++++++++++++++++++- 4 files changed, 208 insertions(+), 27 deletions(-) diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index e7bf0b445..589f269c8 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -65,6 +65,10 @@ raster_datasource::raster_datasource(const parameters& params, bool bind) else filename_ = *file; + multi_tiles_ = *params_.get("multi", false); + tile_size_ = *params_.get("tile-size", 256); + tile_stride_ = *params_.get("tile-stride", 1); + format_=*params_.get("format","tiff"); boost::optional lox = params_.get("lox"); @@ -96,33 +100,50 @@ void raster_datasource::bind() const { if (is_bound_) return; - if (! boost::filesystem::exists(filename_)) - throw datasource_exception("Raster Plugin: " + filename_ + " does not exist"); - - try - { - std::auto_ptr reader(mapnik::get_image_reader(filename_, format_)); - if (reader.get()) - { - width_ = reader->width(); - height_ = reader->height(); + if (multi_tiles_) + { + boost::optional x_width = params_.get("x-width"); + boost::optional y_width = params_.get("y-width"); -#ifdef MAPNIK_DEBUG - std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl; -#endif - } + if (!x_width) + throw datasource_exception("Raster Plugin: x-width parameter not supplied for multi-tiled data source."); + + if (!y_width) + throw datasource_exception("Raster Plugin: y-width parameter not supplied for multi-tiled data source."); + + width_ = x_width.get() * tile_size_; + height_ = y_width.get() * tile_size_; } - catch (mapnik::image_reader_exception const& ex) + else { - std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl; - throw; - } - catch (...) - { - std::cerr << "Raster Plugin: exception caught" << std::endl; - throw; + if (! boost::filesystem::exists(filename_)) + throw datasource_exception("Raster Plugin: " + filename_ + " does not exist"); + + try + { + std::auto_ptr reader(mapnik::get_image_reader(filename_, format_)); + if (reader.get()) + { + width_ = reader->width(); + height_ = reader->height(); + } + } + catch (mapnik::image_reader_exception const& ex) + { + std::cerr << "Raster Plugin: image reader exception caught: " << ex.what() << std::endl; + throw; + } + catch (...) + { + std::cerr << "Raster Plugin: exception caught" << std::endl; + throw; + } } +#ifdef MAPNIK_DEBUG + std::clog << "Raster Plugin: RASTER SIZE(" << width_ << "," << height_ << ")" << std::endl; +#endif + is_bound_ = true; } @@ -165,7 +186,16 @@ featureset_ptr raster_datasource::features(query const& q) const std::clog << "Raster Plugin: BOX SIZE(" << width << " " << height << ")" << std::endl; #endif - if (width * height > 512*512) + if (multi_tiles_) + { +#ifdef MAPNIK_DEBUG + std::clog << "Raster Plugin: MULTI-TILED policy" << std::endl; +#endif + + tiled_multi_file_policy policy(filename_, format_, tile_size_, extent_, q.get_bbox(), width_, height_, tile_stride_); + return boost::make_shared >(policy, extent_, q); + } + else if (width * height > 512*512) { #ifdef MAPNIK_DEBUG std::clog << "Raster Plugin: TILED policy" << std::endl; diff --git a/plugins/input/raster/raster_datasource.hpp b/plugins/input/raster/raster_datasource.hpp index c8f5f4745..d88c45a96 100644 --- a/plugins/input/raster/raster_datasource.hpp +++ b/plugins/input/raster/raster_datasource.hpp @@ -37,6 +37,9 @@ class raster_datasource : public mapnik::datasource std::string format_; mapnik::box2d extent_; bool extent_initialized_; + bool multi_tiles_; + unsigned tile_size_; + unsigned tile_stride_; mutable unsigned width_; mutable unsigned height_; public: diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index 57a797f50..1c463a92b 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -27,6 +27,7 @@ #include "raster_featureset.hpp" +#include using mapnik::query; using mapnik::CoordTransform; @@ -67,16 +68,18 @@ feature_ptr raster_featureset::next() std::clog << "Raster Plugin: READER = " << curIter_->format() << " " << curIter_->file() << " size(" << curIter_->width() << "," << curIter_->height() << ")" << std::endl; #endif + if (reader.get()) { - int image_width=reader->width(); - int image_height=reader->height(); + int image_width = policy_.img_width(reader->width()); + int image_height = policy_.img_height(reader->height()); if (image_width>0 && image_height>0) { CoordTransform t(image_width,image_height,extent_,0,0); box2d intersect=bbox_.intersect(curIter_->envelope()); box2d ext=t.forward(intersect); + box2d rem=policy_.transform(ext); if ( ext.width()>0.5 && ext.height()>0.5 ) { //select minimum raster containing whole ext @@ -96,7 +99,8 @@ feature_ptr raster_featureset::next() int width = end_x - x_off; int height = end_y - y_off; //calculate actual box2d of returned raster - box2d feature_raster_extent(x_off, y_off, x_off+width, y_off+height); + box2d feature_raster_extent(rem.minx() + x_off, rem.miny() + y_off, + rem.maxx() + x_off + width, rem.maxy() + y_off + height); intersect = t.backward(feature_raster_extent); image_data_32 image(width,height); @@ -121,5 +125,20 @@ feature_ptr raster_featureset::next() return feature_ptr(); } +std::string +tiled_multi_file_policy::interpolate(std::string const &pattern, int x, int y) const +{ + // TODO: make from some sort of configurable interpolation + int tms_y = tile_stride_ * ((image_height_ / tile_size_) - y - 1); + int tms_x = tile_stride_ * x; + std::string xs = (boost::format("%03d/%03d/%03d") % (tms_x / 1000000) % ((tms_x / 1000) % 1000) % (tms_x % 1000)).str(); + std::string ys = (boost::format("%03d/%03d/%03d") % (tms_y / 1000000) % ((tms_y / 1000) % 1000) % (tms_y % 1000)).str(); + std::string rv(pattern); + boost::algorithm::replace_all(rv, "${x}", xs); + boost::algorithm::replace_all(rv, "${y}", ys); + return rv; +} + template class raster_featureset; template class raster_featureset; +template class raster_featureset; diff --git a/plugins/input/raster/raster_featureset.hpp b/plugins/input/raster/raster_featureset.hpp index 879b2e848..4c2bb9816 100644 --- a/plugins/input/raster/raster_featureset.hpp +++ b/plugins/input/raster/raster_featureset.hpp @@ -29,7 +29,7 @@ // boost #include - +#include class single_file_policy { @@ -95,6 +95,21 @@ public: { return const_iterator(); } + + inline int img_width(int reader_width) const + { + return reader_width; + } + + inline int img_height(int reader_height) const + { + return reader_height; + } + + inline box2d transform(box2d &) const + { + return box2d(0, 0, 0, 0); + } }; class tiled_file_policy @@ -154,11 +169,125 @@ public: return infos_.end(); } + inline int img_width(int reader_width) const + { + return reader_width; + } + + inline int img_height(int reader_height) const + { + return reader_height; + } + + inline box2d transform(box2d &) const + { + return box2d(0, 0, 0, 0); + } + private: std::vector infos_; }; +class tiled_multi_file_policy +{ +public: + + typedef std::vector::const_iterator const_iterator; + + tiled_multi_file_policy(std::string const& file_pattern, std::string const& format, unsigned tile_size, + box2d extent, box2d bbox,unsigned width, unsigned height, + unsigned tile_stride) + : image_width_(width), image_height_(height), tile_size_(tile_size), tile_stride_(tile_stride) + { + + double lox = extent.minx(); + double loy = extent.miny(); + + int max_x = int(std::ceil(double(width)/double(tile_size))); + int max_y = int(std::ceil(double(height)/double(tile_size))); + + double pixel_x = extent.width()/double(width); + double pixel_y = extent.height()/double(height); + +#ifdef MAPNIK_DEBUG + std::clog << "Raster Plugin: PIXEL SIZE("<< pixel_x << "," << pixel_y << ")" << std::endl; +#endif + + // intersection of query with extent => new query + box2d e = bbox.intersect(extent); + + const int x_min = int(std::floor((e.minx() - lox) / (tile_size * pixel_x))); + const int y_min = int(std::floor((e.miny() - loy) / (tile_size * pixel_y))); + const int x_max = int(std::ceil((e.maxx() - lox) / (tile_size * pixel_x))); + const int y_max = int(std::ceil((e.maxy() - loy) / (tile_size * pixel_y))); + + for (int x = x_min ; x < x_max ; ++x) + { + for (int y = y_min ; y < y_max ; ++y) + { + // x0, y0, x1, y1 => projection-space image coordinates. + double x0 = lox + x*tile_size*pixel_x; + double y0 = loy + y*tile_size*pixel_y; + double x1 = x0 + tile_size*pixel_x; + double y1 = y0 + tile_size*pixel_y; + + // check if it intersects the query + if (e.intersects(box2d(x0,y0,x1,y1))) + { + // tile_box => intersection of tile with query in projection-space. + box2d tile_box = e.intersect(box2d(x0,y0,x1,y1)); + std::string file = interpolate(file_pattern, x, y); + raster_info info(file,format,tile_box,tile_size,tile_size); + infos_.push_back(info); + } + } + } +#ifdef MAPNIK_DEBUG + std::clog << "Raster Plugin: INFO SIZE=" << infos_.size() << " " << file_pattern << std::endl; +#endif + } + + const_iterator begin() + { + return infos_.begin(); + } + + const_iterator end() + { + return infos_.end(); + } + + inline int img_width(int) const + { + return image_width_; + } + + inline int img_height(int) const + { + return image_height_; + } + + inline box2d transform(box2d &box) const + { + int x_offset = int(std::floor(box.minx() / tile_size_)); + int y_offset = int(std::floor(box.miny() / tile_size_)); + box2d rem(x_offset * tile_size_, y_offset * tile_size_, + x_offset * tile_size_, y_offset * tile_size_); + box.init(box.minx() - rem.minx(), + box.miny() - rem.miny(), + box.maxx() - rem.maxx(), + box.maxy() - rem.maxy()); + return rem; + } + +private: + + std::string interpolate(std::string const &pattern, int x, int y) const; + + unsigned int image_width_, image_height_, tile_size_, tile_stride_; + std::vector infos_; +}; template class raster_featureset : public mapnik::Featureset From b05a51c783bf55581237f30f6786f8280d80f96f Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Wed, 12 Oct 2011 01:25:10 +0100 Subject: [PATCH 03/33] Ooops, added missing file from patch. --- .../mapnik_label_collision_detector.cpp | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 bindings/python/mapnik_label_collision_detector.cpp diff --git a/bindings/python/mapnik_label_collision_detector.cpp b/bindings/python/mapnik_label_collision_detector.cpp new file mode 100644 index 000000000..b7a38d8b6 --- /dev/null +++ b/bindings/python/mapnik_label_collision_detector.cpp @@ -0,0 +1,123 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2011 MapQuest + * + * 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 + * + *****************************************************************************/ + +#include +#include +#include + +#include +#include + +#include + +using mapnik::label_collision_detector4; +using mapnik::box2d; +using mapnik::Map; + +namespace +{ + +boost::shared_ptr +create_label_collision_detector_from_extent(box2d const &extent) +{ + return boost::shared_ptr( + new label_collision_detector4(extent)); +} + +boost::shared_ptr +create_label_collision_detector_from_map(Map const &m) +{ + double buffer = m.buffer_size(); + box2d extent(-buffer, -buffer, m.width() + buffer, m.height() + buffer); + return boost::shared_ptr( + new label_collision_detector4(extent)); +} + +boost::python::list +make_label_boxes(boost::shared_ptr det) +{ + boost::python::list boxes; + + for (label_collision_detector4::query_iterator jtr = det->begin(); + jtr != det->end(); ++jtr) + { + boxes.append >(jtr->box); + } + + return boxes; +} + +} + +void export_label_collision_detector() +{ + using namespace boost::python; + + // for overload resolution + void (label_collision_detector4::*insert_box)(box2d const &) = &label_collision_detector4::insert; + + class_, boost::noncopyable> + ("LabelCollisionDetector", + "Object to detect collisions between labels, used in the rendering process.", + no_init) + + .def("__init__", make_constructor(create_label_collision_detector_from_extent), + "Creates an empty collision detection object with a given extent. Note " + "that the constructor from Map objects is a sensible default and usually " + "what you want to do.\n" + "\n" + "Example:\n" + ">>> m = Map(size_x, size_y)\n" + ">>> buf_sz = m.buffer_size\n" + ">>> extent = mapnik.Box2d(-buf_sz, -buf_sz, m.width + buf_sz, m.height + buf_sz)\n" + ">>> detector = mapnik.LabelCollisionDetector(extent)") + + .def("__init__", make_constructor(create_label_collision_detector_from_map), + "Creates an empty collision detection object matching the given Map object. " + "The created detector will have the same size, including the buffer, as the " + "map object. This is usually what you want to do.\n" + "\n" + "Example:\n" + ">>> m = Map(size_x, size_y)\n" + ">>> detector = mapnik.LabelCollisionDetector(m)") + + .def("extent", &label_collision_detector4::extent, return_value_policy(), + "Returns the total extent (bounding box) of all labels inside the detector.\n" + "\n" + "Example:\n" + ">>> detector.extent()\n" + "Box2d(573.252589209,494.789179821,584.261023823,496.83610261)") + + .def("boxes", &make_label_boxes, + "Returns a list of all the label boxes inside the detector.") + + .def("insert", insert_box, + "Insert a 2d box into the collision detector. This can be used to ensure that " + "some space is left clear on the map for later overdrawing, for example by " + "non-Mapnik processes.\n" + "\n" + "Example:\n" + ">>> m = Map(size_x, size_y)\n" + ">>> detector = mapnik.LabelCollisionDetector(m)" + ">>> detector.insert(mapnik.Box2d(196, 254, 291, 389))") + ; +} From 1717104654a0c95778d35ee8788f3685d5a33e52 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Wed, 12 Oct 2011 01:37:44 +0100 Subject: [PATCH 04/33] Changed copyright notice in line with project convention. --- bindings/python/mapnik_label_collision_detector.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/mapnik_label_collision_detector.cpp b/bindings/python/mapnik_label_collision_detector.cpp index b7a38d8b6..f207255a7 100644 --- a/bindings/python/mapnik_label_collision_detector.cpp +++ b/bindings/python/mapnik_label_collision_detector.cpp @@ -2,7 +2,7 @@ * * This file is part of Mapnik (c++ mapping toolkit) * - * Copyright (C) 2011 MapQuest + * 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 From a2b4f9db5950bfda4d70d82c5f02030fe198ab16 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Thu, 13 Oct 2011 19:34:28 +0100 Subject: [PATCH 05/33] Use make_shared as suggested by coding guidelines. --- bindings/python/mapnik_label_collision_detector.cpp | 8 ++++---- src/agg/agg_renderer.cpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bindings/python/mapnik_label_collision_detector.cpp b/bindings/python/mapnik_label_collision_detector.cpp index f207255a7..c81c6191a 100644 --- a/bindings/python/mapnik_label_collision_detector.cpp +++ b/bindings/python/mapnik_label_collision_detector.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ using mapnik::label_collision_detector4; using mapnik::box2d; using mapnik::Map; +using boost::make_shared; namespace { @@ -39,8 +41,7 @@ namespace boost::shared_ptr create_label_collision_detector_from_extent(box2d const &extent) { - return boost::shared_ptr( - new label_collision_detector4(extent)); + return make_shared(extent); } boost::shared_ptr @@ -48,8 +49,7 @@ create_label_collision_detector_from_map(Map const &m) { double buffer = m.buffer_size(); box2d extent(-buffer, -buffer, m.width() + buffer, m.height() + buffer); - return boost::shared_ptr( - new label_collision_detector4(extent)); + return make_shared(extent); } boost::python::list diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index bcdc8ef12..ae482aa32 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -73,7 +73,7 @@ // boost #include - +#include // stl #ifdef MAPNIK_DEBUG @@ -121,7 +121,7 @@ agg_renderer::agg_renderer(Map const& m, T & pixmap, double scale_factor, uns t_(m.width(),m.height(),m.get_current_extent(),offset_x,offset_y), font_engine_(), font_manager_(font_engine_), - detector_(new label_collision_detector4(box2d(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))), + detector_(boost::make_shared(box2d(-m.buffer_size(), -m.buffer_size(), m.width() + m.buffer_size() ,m.height() + m.buffer_size()))), ras_ptr(new rasterizer) { setup(m); From 517fc59f77192cdf188503fd9b16d7b24f70f8c9 Mon Sep 17 00:00:00 2001 From: Matt Amos Date: Tue, 18 Oct 2011 14:34:58 +0100 Subject: [PATCH 06/33] Added Python test for multi-tile raster policy. --- bindings/python/mapnik/__init__.py | 7 ++ plugins/input/raster/raster_datasource.cpp | 8 +- .../raster_tiles/000/000/000/000/000/000.tif | Bin 0 -> 3427 bytes .../raster_tiles/000/000/000/000/000/001.tif | Bin 0 -> 3427 bytes .../raster_tiles/000/000/001/000/000/000.tif | Bin 0 -> 3427 bytes .../raster_tiles/000/000/001/000/000/001.tif | Bin 0 -> 3423 bytes tests/python_tests/multi_tile_raster_test.py | 70 ++++++++++++++++++ 7 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 tests/data/raster_tiles/000/000/000/000/000/000.tif create mode 100644 tests/data/raster_tiles/000/000/000/000/000/001.tif create mode 100644 tests/data/raster_tiles/000/000/001/000/000/000.tif create mode 100644 tests/data/raster_tiles/000/000/001/000/000/001.tif create mode 100644 tests/python_tests/multi_tile_raster_test.py diff --git a/bindings/python/mapnik/__init__.py b/bindings/python/mapnik/__init__.py index 6eac1d6d9..2ed760e73 100644 --- a/bindings/python/mapnik/__init__.py +++ b/bindings/python/mapnik/__init__.py @@ -410,6 +410,13 @@ def Raster(**keywords): Optional keyword arguments: base -- path prefix (default None) + multi -- whether the image is in tiles on disk (default False) + + Multi-tiled keyword arguments: + x_width -- virtual image number of tiles in X direction (required) + y_width -- virtual image number of tiles in Y direction (required) + tile_size -- if an image is in tiles, how large are the tiles (default 256) + tile_stride -- if an image is in tiles, what's the increment between rows/cols (default 1) >>> from mapnik import Raster, Layer >>> raster = Raster(base='/home/mapnik/data',file='elevation.tif',lox=-122.8,loy=48.5,hix=-122.7,hiy=48.6) diff --git a/plugins/input/raster/raster_datasource.cpp b/plugins/input/raster/raster_datasource.cpp index 589f269c8..20b363650 100644 --- a/plugins/input/raster/raster_datasource.cpp +++ b/plugins/input/raster/raster_datasource.cpp @@ -66,8 +66,8 @@ raster_datasource::raster_datasource(const parameters& params, bool bind) filename_ = *file; multi_tiles_ = *params_.get("multi", false); - tile_size_ = *params_.get("tile-size", 256); - tile_stride_ = *params_.get("tile-stride", 1); + tile_size_ = *params_.get("tile_size", 256); + tile_stride_ = *params_.get("tile_stride", 1); format_=*params_.get("format","tiff"); @@ -102,8 +102,8 @@ void raster_datasource::bind() const if (multi_tiles_) { - boost::optional x_width = params_.get("x-width"); - boost::optional y_width = params_.get("y-width"); + boost::optional x_width = params_.get("x_width"); + boost::optional y_width = params_.get("y_width"); if (!x_width) throw datasource_exception("Raster Plugin: x-width parameter not supplied for multi-tiled data source."); diff --git a/tests/data/raster_tiles/000/000/000/000/000/000.tif b/tests/data/raster_tiles/000/000/000/000/000/000.tif new file mode 100644 index 0000000000000000000000000000000000000000..d43cebc820fdc297a711e7a12f0085f948d94f8c GIT binary patch literal 3427 zcmebD)M7Zo#lZ0Y#{b(4&I}xEZ0u~T9PI4uoSYn7JR-b2+}u2pLc;tavQqMLvQjcK z3MzW)3Q9W4GBO(GnmPuCCMG8G>Xx<^MmBoJCPx1cFbHxmI509WGYB#;3NkPWGW@^A zz{AYIz{tSFz+lht^WWZo`|1~UX^f)L5Fj%I_W!>*np{V7&`=41(d0T*VrtZ#zz`Ts zuA|9d2!#MJxe7D>Vtc+j)G#m^V znV4Bv+1NQaxw!uyVc06b0E|UuCKhH^Ru*7ECr+Nabot8FYu9hwy!G(W<0ns_J%91?)yGetzkL1n{m0K=|8D{S!C&GN literal 0 HcmV?d00001 diff --git a/tests/data/raster_tiles/000/000/000/000/000/001.tif b/tests/data/raster_tiles/000/000/000/000/000/001.tif new file mode 100644 index 0000000000000000000000000000000000000000..67d3bb67aba24b66cf30cc7f7c7a5e7b4c6c4118 GIT binary patch literal 3427 zcmebD)M7Zo#lZ0Y#{b(4&I}xEZ0u~T9PI4uoSYn7JR-b2+}u2pLc;tavQqMLvQjcK z3MzW)3Q9W4GBO(GnmPuCCMG8G>Xx<^MmBoJCPx1cFbHxmI509WGYB#;3NkPWGW@^A zz{AYIz{tSFz+lht{nyWb`|1~UX^f)L5Fj%I_W!>*np{V7&`=41(d0T*VrtZ#zz`Ts zuA|9d2!#MJxe7DR;@QBE$ z5`HGdRHf`Rrb=&qG zJ9iyAeB|h{<0np@x^(%<)oa&p+`RSh(c>pipFMx^^3}&rpTB(l_Wj4tU;l3c07(7f A>;M1& literal 0 HcmV?d00001 diff --git a/tests/data/raster_tiles/000/000/001/000/000/000.tif b/tests/data/raster_tiles/000/000/001/000/000/000.tif new file mode 100644 index 0000000000000000000000000000000000000000..0868eeaf089e0a01fc469945ec40551861f20080 GIT binary patch literal 3427 zcmebD)M7Zo#lZ0Y#{b(4&I}xEZ0u~T9PI4uoSYn7JR-b2+}u2pLc;tavQqMLvQjcK z3MzW)3Q9W4GBO(GnmPuCCMG8G>Xx<^MmBoJCPx1cFbHxmI509WGYB#;3NkPWGW@^A zz{AYIz{tSFz+lht^WVPu_4SLoG)B>A2#^^9`~Tk@O|GLkXsCq1XmTAYF*WK=US{3Nli=7$jmA(DJ?6nsH|#kX>Duo= literal 0 HcmV?d00001 diff --git a/tests/data/raster_tiles/000/000/001/000/000/001.tif b/tests/data/raster_tiles/000/000/001/000/000/001.tif new file mode 100644 index 0000000000000000000000000000000000000000..95eee548c7acef62840e02321af776a67dd1f7b2 GIT binary patch literal 3423 zcmebD)M7Zm#lZ0Y#{b(4&I}xEZ0u~T9PI4uoSYn7JR-b2+}u2pLc;tavQqMLvQjcK z3MzW)3Q9W4GBO(GnmPuCCMG8G>Xx<^MmBoJCPx1cFbHxmI509WGYB#;3NkPWGW@^A zz{AYIz{tSFz+lht{nyWbd;fK5EE+|lAwXsb{J%MxT1PX`Pziz2)H+($51kMgO|3&G zu7*kpNIQ4_zbVY{kAVf)xP$^mW(XT7z=*_V0KO&NF@ znHao*^ah|BJ|J5N$o>Ol3o^0*Z2*e#Ffa%~)r0I4g|b2Bib2^9K(;tky&O=z6eBCx zJ$gX4G?Z-yWXm9#qXA`u+z`#k&Y%c1+zweFFmnC^kf9>y>1tF)%n6r6!i7 zrYMwWmSiZnd-?_dZD3&72DC1P6=*+@vku5c#z1KgAO?9KOjD~Jc7#D5Xeuis7yu0i z14brh7FITP4o)ua|3?_M3NQd;k(r5wnU$3V7$1zaKzRlhK~^C}Lq|5@z(jVXLJ_0J zi3>TDoi-j64Z8S2#W<;`iIYoATtZSxRZU$(Q_IBE%-q7#%Gt%$&E3P(D>x)HEIcAI zDmf)JEj=SMtGJ}Jth}PKs=1}Lt-YhOYtrN?Q>RUzF>}_U#Y>hhTfSoDs!f}>Y~8kf z$Ie}c4j(ys?D&b3r!HN-a`oEv8#iw~eDwIq(`V0LynOZX)8{W=zkUDl^Vk2I0HclK AS^xk5 literal 0 HcmV?d00001 diff --git a/tests/python_tests/multi_tile_raster_test.py b/tests/python_tests/multi_tile_raster_test.py new file mode 100644 index 000000000..65a29675f --- /dev/null +++ b/tests/python_tests/multi_tile_raster_test.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +from nose.tools import * +from utilities import execution_path, save_data, contains_word + +import os, mapnik2 + +def setup(): + # All of the paths used are relative, if we run the tests + # from another directory we need to chdir() + os.chdir(execution_path('.')) + +def test_multi_tile_policy(): + srs = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' + lyr = mapnik2.Layer('raster') + lyr.datasource = mapnik2.Raster( + file = '../data/raster_tiles/${x}/${y}.tif', + lox = -180, + loy = -90, + hix = 180, + hiy = 90, + multi = 1, + tile_size = 256, + x_width = 2, + y_width = 2 + ) + lyr.srs = srs + _map = mapnik2.Map(256, 256, srs) + style = mapnik2.Style() + rule = mapnik2.Rule() + sym = mapnik2.RasterSymbolizer() + rule.symbols.append(sym) + style.rules.append(rule) + _map.append_style('foo', style) + lyr.styles.append('foo') + _map.layers.append(lyr) + _map.zoom_to_box(lyr.envelope()) + + im = mapnik2.Image(_map.width, _map.height) + mapnik2.render(_map, im) + + save_data('test_multi_tile_policy.png', im.tostring('png')) + + # test green chunk + assert im.view(0,64,1,1).tostring() == '\x00\xff\x00\xff' + assert im.view(127,64,1,1).tostring() == '\x00\xff\x00\xff' + assert im.view(0,127,1,1).tostring() == '\x00\xff\x00\xff' + assert im.view(127,127,1,1).tostring() == '\x00\xff\x00\xff' + + # test blue chunk + assert im.view(128,64,1,1).tostring() == '\x00\x00\xff\xff' + assert im.view(255,64,1,1).tostring() == '\x00\x00\xff\xff' + assert im.view(128,127,1,1).tostring() == '\x00\x00\xff\xff' + assert im.view(255,127,1,1).tostring() == '\x00\x00\xff\xff' + + # test red chunk + assert im.view(0,128,1,1).tostring() == '\xff\x00\x00\xff' + assert im.view(127,128,1,1).tostring() == '\xff\x00\x00\xff' + assert im.view(0,191,1,1).tostring() == '\xff\x00\x00\xff' + assert im.view(127,191,1,1).tostring() == '\xff\x00\x00\xff' + + # test magenta chunk + assert im.view(128,128,1,1).tostring() == '\xff\x00\xff\xff' + assert im.view(255,128,1,1).tostring() == '\xff\x00\xff\xff' + assert im.view(128,191,1,1).tostring() == '\xff\x00\xff\xff' + assert im.view(255,191,1,1).tostring() == '\xff\x00\xff\xff' + +if __name__ == "__main__": + setup() + [eval(run)() for run in dir() if 'test_' in run] From a1e73ad1c641b8f0378f283889b6404c64c85a8e Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 18:19:02 -0700 Subject: [PATCH 07/33] Add 0.7.2 changelog to master changelog --- CHANGELOG | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 7beaa09fc..920a5bde6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -110,6 +110,50 @@ Mapnik 2.0.0 - Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553) +Mapnik 0.7.2 Release +-------------------- + +- Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes) + +- Build fixes to ensure boost_threads are not used unless THREADING=multi build option is used + +- Fixes for the clang compiler + +- Support for latest libpng (>= 1.5.x) (r2999) + +- Fixes to the postgres pool + +- Fix for correct transparency levels in png256/png8 output (#540) + +- Various build system fixes, especially for gcc compiler on open solaris. + +- When plugins are not found, report the searched directories (#568) + +- Improved font loading support (#559) + +- Fix to shapeindex for allowing indexing of directory of shapefiles like `shapeindex dir/*shp` + +- Fixed handling of null and multipatch shapes in shapefile driver - avoiding inf loop (#573) + +- Fixed raster alpha blending (#589,#674) + +- Enhanced support for faster reprojection if proj >= 4.8 is used (#575) + +- Allow for late-binding of datasources (#622) + +- Fix to OSM plugin to avoid over-caching of data (#542) + +- Various fixes to sqlite, ogr, and occi driver backported from trunk. + +- Ensured that '\n' triggers linebreaks in text rendering (#584) + +- Support for boost filesystem v3 + +- Fixes to cairo renderer to avoid missing images (r2526) + +- Fixed reading of label_position_tolerance on text_symbolizer and height for building_symbolizer + + Mapnik 0.7.0 Release -------------------- From 016527549c68743184506954984917adccca7670 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 18:19:32 -0700 Subject: [PATCH 08/33] add a big group of csv test cases --- tests/data/csv/blank_rows.csv | 9 +++++++++ tests/data/csv/empty_rows.csv | 5 +++++ tests/data/csv/fails/blank.csv | 1 + .../csv/{points.vrt => fails/cannot_read_a_vrt.vrt} | 0 tests/data/csv/fails/invalid_geometries.csv | 3 +++ tests/data/csv/fails/invalid_wkt.csv | 2 ++ tests/data/csv/fails/mixed_separators.csv | 2 ++ tests/data/csv/fails/no_geometry.csv | 2 ++ tests/data/csv/fails/no_headers.csv | 1 + tests/data/csv/has_attributes_with_slashes.csv | 4 ++++ tests/data/csv/mac_newlines.csv | 1 + tests/data/csv/tabs.tsv | 3 +++ tests/data/csv/tabs_in_csv.csv | 2 ++ tests/data/csv/unicode.tsv | 11 +++++++++++ tests/data/csv/untitled file | 0 tests/data/csv/warns/invalid_geometries.csv | 3 +++ tests/data/csv/windows_newlines.csv | 2 ++ tests/data/csv/wkt.csv | 9 +++++++++ tests/data/good_maps/point_csv.xml | 2 +- tests/data/vrt/points.vrt | 8 ++++++++ 20 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/data/csv/blank_rows.csv create mode 100644 tests/data/csv/empty_rows.csv create mode 100644 tests/data/csv/fails/blank.csv rename tests/data/csv/{points.vrt => fails/cannot_read_a_vrt.vrt} (100%) create mode 100644 tests/data/csv/fails/invalid_geometries.csv create mode 100644 tests/data/csv/fails/invalid_wkt.csv create mode 100644 tests/data/csv/fails/mixed_separators.csv create mode 100644 tests/data/csv/fails/no_geometry.csv create mode 100644 tests/data/csv/fails/no_headers.csv create mode 100644 tests/data/csv/has_attributes_with_slashes.csv create mode 100644 tests/data/csv/mac_newlines.csv create mode 100644 tests/data/csv/tabs.tsv create mode 100644 tests/data/csv/tabs_in_csv.csv create mode 100644 tests/data/csv/unicode.tsv create mode 100644 tests/data/csv/untitled file create mode 100644 tests/data/csv/warns/invalid_geometries.csv create mode 100644 tests/data/csv/windows_newlines.csv create mode 100644 tests/data/csv/wkt.csv create mode 100644 tests/data/vrt/points.vrt diff --git a/tests/data/csv/blank_rows.csv b/tests/data/csv/blank_rows.csv new file mode 100644 index 000000000..82698cacb --- /dev/null +++ b/tests/data/csv/blank_rows.csv @@ -0,0 +1,9 @@ + + + +x,y,name +0,0,a + + +0,0,b + diff --git a/tests/data/csv/empty_rows.csv b/tests/data/csv/empty_rows.csv new file mode 100644 index 000000000..d1d0cd26e --- /dev/null +++ b/tests/data/csv/empty_rows.csv @@ -0,0 +1,5 @@ +x,y,text,date,integer,boolean,float,time,datetime,empty_column +0,0,a b,1971-01-01,40,True,1.0,04:14:00,1971-01-01T04:14:00, +0,0,c d,1948-01-01,63,True,1.27,14:57:13,1948-01-01T14:57:13, +0,0,e f,1920-01-01,164,False,41800000.01,00:00:00,1920-01-01T00:00:00, +0,0,This row has empties,,,,,,, \ No newline at end of file diff --git a/tests/data/csv/fails/blank.csv b/tests/data/csv/fails/blank.csv new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/tests/data/csv/fails/blank.csv @@ -0,0 +1 @@ + diff --git a/tests/data/csv/points.vrt b/tests/data/csv/fails/cannot_read_a_vrt.vrt similarity index 100% rename from tests/data/csv/points.vrt rename to tests/data/csv/fails/cannot_read_a_vrt.vrt diff --git a/tests/data/csv/fails/invalid_geometries.csv b/tests/data/csv/fails/invalid_geometries.csv new file mode 100644 index 000000000..6763f08dc --- /dev/null +++ b/tests/data/csv/fails/invalid_geometries.csv @@ -0,0 +1,3 @@ +x,y,z +-122a,48b,bogus +-122,48,fine \ No newline at end of file diff --git a/tests/data/csv/fails/invalid_wkt.csv b/tests/data/csv/fails/invalid_wkt.csv new file mode 100644 index 000000000..c4de2265d --- /dev/null +++ b/tests/data/csv/fails/invalid_wkt.csv @@ -0,0 +1,2 @@ +wkt,name +"POINT (a b)",one \ No newline at end of file diff --git a/tests/data/csv/fails/mixed_separators.csv b/tests/data/csv/fails/mixed_separators.csv new file mode 100644 index 000000000..323b95d64 --- /dev/null +++ b/tests/data/csv/fails/mixed_separators.csv @@ -0,0 +1,2 @@ +x y name +-122, 48, hello \ No newline at end of file diff --git a/tests/data/csv/fails/no_geometry.csv b/tests/data/csv/fails/no_geometry.csv new file mode 100644 index 000000000..dda0f126d --- /dev/null +++ b/tests/data/csv/fails/no_geometry.csv @@ -0,0 +1,2 @@ +a,b,c,d,e,f,g +1,2,3,4,5,6,7 \ No newline at end of file diff --git a/tests/data/csv/fails/no_headers.csv b/tests/data/csv/fails/no_headers.csv new file mode 100644 index 000000000..ae5344d22 --- /dev/null +++ b/tests/data/csv/fails/no_headers.csv @@ -0,0 +1 @@ +-122,48,place \ No newline at end of file diff --git a/tests/data/csv/has_attributes_with_slashes.csv b/tests/data/csv/has_attributes_with_slashes.csv new file mode 100644 index 000000000..b9ceb29f0 --- /dev/null +++ b/tests/data/csv/has_attributes_with_slashes.csv @@ -0,0 +1,4 @@ +x,y,name +0,0,a/a +1,4,b/b +10,2.5,c/c \ No newline at end of file diff --git a/tests/data/csv/mac_newlines.csv b/tests/data/csv/mac_newlines.csv new file mode 100644 index 000000000..f18abbd0b --- /dev/null +++ b/tests/data/csv/mac_newlines.csv @@ -0,0 +1 @@ +x,y,z 1,10,0 \ No newline at end of file diff --git a/tests/data/csv/tabs.tsv b/tests/data/csv/tabs.tsv new file mode 100644 index 000000000..be33ff870 --- /dev/null +++ b/tests/data/csv/tabs.tsv @@ -0,0 +1,3 @@ +x y name +-122 48 hello +0 0 "null island" \ No newline at end of file diff --git a/tests/data/csv/tabs_in_csv.csv b/tests/data/csv/tabs_in_csv.csv new file mode 100644 index 000000000..1137f4ae7 --- /dev/null +++ b/tests/data/csv/tabs_in_csv.csv @@ -0,0 +1,2 @@ +x, y,z +-122 , 48,0 \ No newline at end of file diff --git a/tests/data/csv/unicode.tsv b/tests/data/csv/unicode.tsv new file mode 100644 index 000000000..d3e2a3c54 --- /dev/null +++ b/tests/data/csv/unicode.tsv @@ -0,0 +1,11 @@ +geonameid name asciiname alternatenames latitude longitude feature_class feature_code country_code cc2 admin1 admin2 admin3 admin4 population elevation gtopo3 timezone mod_date +725712 Vratsa Vratsa Vraca,Vratca,Vratsa,Vrattsa,Vratza,Wraza,Враца 43.21 23.5625 P PPLA BG 64 VRC10 64941 341 Europe/Sofia 2011-10-10 +725816 Sveti Vlas Sveti Vlas Manasturkioy,Manastŭrkioy,Monasturkioy,Monastŭrkioy,Saint Vlas,Sveti Vlas,Sveti-Vlas,Sweti Wlas,Vlas,Влас,Свети-Влас 42.7136 27.75867 P PPL BG BG 39 BGS15 BGS15-02 3875 50 -9999 Europe/Sofia 2010-03-07 +725905 Vidin Vidin Vidin,Vidine,Widin,wydyn,Видин,ویدین 43.99 22.8725 P PPLA BG 63 VID09 54409 35 Europe/Sofia 2011-10-10 +725924 Vetrino Vetrino Asya-Tepe,Jasi Tepe,Vetrino,Vyetreno,Vyetrino,Wetrino,Yasa-Tepe,Yase-Tepe,Yasu-Tepe,Yasă-Tepe,Yasŭ-Tepe,Ветрино 43.31667 27.43333 P PPL BG BG 61 VAR08 1368 223 Europe/Sofia 2011-10-10 +725935 Vetovo Vetovo Vetova,Vetovo,Vjetevo,Vyetovo,Wetowo,Ветово 43.7 26.26667 P PPL BG 53 RSE05 5175 184 Europe/Sofia 2007-04-05 +725967 Venets Venets K'okledzha,K'oklyudzha,K'okyudzha,Kiokhudza,Kiokhudža,Kokedzha,K’okledzha,K’oklyudzha,K’okyudzha,Venec,Venets,Vyenets,Wenez,Венец 43.55 26.93333 P PPL BG BG 54 SHU07 1450 334 Europe/Sofia 2011-10-10 +725988 Velingrad Velingrad Velingrad,Велинград 42.02724 23.99569 P PPL BG 48 PAZ08 24036 745 Europe/Sofia 2010-05-28 +725993 Veliko Tŭrnovo Veliko Turnovo Tarnovo,Tarnowo,Ternovo,Tirnovo,Trnova,Trnovo,Turnovo,Tărnovo,Tărnowo,Tŭrnovo,Veliko T\"rnovo,Veliko Tarnovo,Veliko Tărnovo,Weliko Tarnowo,Weliko Tyrnowo,vu~erikotarunovu~o,Велико Търново,ヴェリコタルノヴォ 43.08124 25.62904 P PPLA BG 62 VTR04 66217 162 Europe/Sofia 2007-07-01 +726050 Varna Varna Barna,Odessos,Odessus,Stalin,Varna,Warna,farna,varna,vu~aruna,wa er na,wrnh,Βάρνα,Варна,ורנה,فارنا,ვარნა,ヴァルナ,瓦爾納 43.21667 27.91667 P PPLA BG 61 VAR06 312770 95 Europe/Sofia 2011-10-10 +726114 Ugŭrchin Ugurchin Ugarchin,Ugarcin,Ugartschin,Ugarčin,Ugirkin,Ugrchin,Ugrcin,Ugrčin,Ugurchin,Ugurcin,Ugürčin,Ugărchin,Ugărtschin,Угърчин 43.1 24.41667 P PPL BG 46 LOV36 2965 298 Europe/Sofia 2007-04-05 diff --git a/tests/data/csv/untitled file b/tests/data/csv/untitled file new file mode 100644 index 000000000..e69de29bb diff --git a/tests/data/csv/warns/invalid_geometries.csv b/tests/data/csv/warns/invalid_geometries.csv new file mode 100644 index 000000000..6763f08dc --- /dev/null +++ b/tests/data/csv/warns/invalid_geometries.csv @@ -0,0 +1,3 @@ +x,y,z +-122a,48b,bogus +-122,48,fine \ No newline at end of file diff --git a/tests/data/csv/windows_newlines.csv b/tests/data/csv/windows_newlines.csv new file mode 100644 index 000000000..3a6e88b89 --- /dev/null +++ b/tests/data/csv/windows_newlines.csv @@ -0,0 +1,2 @@ +x,y,z +0,0,0 \ No newline at end of file diff --git a/tests/data/csv/wkt.csv b/tests/data/csv/wkt.csv new file mode 100644 index 000000000..201ff899b --- /dev/null +++ b/tests/data/csv/wkt.csv @@ -0,0 +1,9 @@ +type,WKT +point, "POINT (30 10)" +linestring, "LINESTRING (30 10, 10 30, 40 40)" +polygon, "POLYGON ((30 10, 10 20, 20 40, 40 40, 30 10))" +polygon, "POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))" +multipoint, "MULTIPOINT ((10 40), (40 30), (20 20), (30 10))" +multilinestring, "MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))" +multipolygon, "MULTIPOLYGON (((30 20, 10 40, 45 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))" +multipolygon, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)),((20 35, 45 20, 30 5, 10 10, 10 30, 20 35),(30 20, 20 25, 20 15, 30 20)))" \ No newline at end of file diff --git a/tests/data/good_maps/point_csv.xml b/tests/data/good_maps/point_csv.xml index ef2cc4de3..fc36de8c7 100644 --- a/tests/data/good_maps/point_csv.xml +++ b/tests/data/good_maps/point_csv.xml @@ -22,7 +22,7 @@ 1 - ../csv/points.vrt + ../vrt/points.vrt 0 ogr diff --git a/tests/data/vrt/points.vrt b/tests/data/vrt/points.vrt new file mode 100644 index 000000000..e40d87086 --- /dev/null +++ b/tests/data/vrt/points.vrt @@ -0,0 +1,8 @@ + + + ../csv/points.csv + wkbPoint + WGS84 + + + \ No newline at end of file From 0cd3048e6064a9322f5179bb2b278a45ef178d43 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 18:21:19 -0700 Subject: [PATCH 09/33] csv plugin: fix newlines detectio, fix first feature detection, and work around spirit number parsing issues --- plugins/input/csv/csv_datasource.cpp | 110 ++++++++++++++++++--------- 1 file changed, 72 insertions(+), 38 deletions(-) diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index 35aba2977..c1a8a0b4a 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -125,10 +125,11 @@ void csv_datasource::parse_csv(T& stream, std::string const& separator, std::string const& quote) const { + stream.seekg (0, std::ios::end); + int file_length_ = stream.tellg(); + if (filesize_max_ > 0) { - stream.seekg (0, std::ios::end); - int file_length_ = stream.tellg(); double file_mb = static_cast(file_length_)/1048576; // throw if this is an unreasonably large file to read into memory @@ -140,35 +141,49 @@ void csv_datasource::parse_csv(T& stream, << " to render this data (set 'filesize_max=0' to disable this restriction if you have lots of memory)"; throw mapnik::datasource_exception(s.str()); } - - // set back to start - stream.seekg (0, std::ios::beg); } - char newline; - std::string csv_line; + // set back to start + stream.seekg (0, std::ios::beg); // autodetect newlines - bool found_break = false; - if (std::getline(stream,csv_line,'\n')) + char newline = '\n'; + int newline_count = 0; + int carriage_count = 0; + for(std::size_t idx = 0; idx < file_length_; idx++) { - found_break = true; - newline = '\n'; + char c = static_cast(stream.get()); + if (c == '\n') + { + ++newline_count; + } + else if (c == '\r') + { + ++carriage_count; + } + // read at least 2000 bytes before testing + if (idx == file_length_-1 || idx > 4000) + { + if (newline_count > carriage_count) + { + break; + } + else if (carriage_count > newline_count) + { + newline = '\r'; + break; + } + } } - else if (std::getline(stream,csv_line,'\r')) - { - found_break = true; - newline = '\r'; - } - else - { - throw mapnik::datasource_exception("CSV Plugin: could not detect any line breaks in this csv (http://en.wikipedia.org/wiki/Newline)\n"); - } - + // set back to start stream.seekg (0, std::ios::beg); - // if user has not passed separator manuall + // get first line + std::string csv_line; + std::getline(stream,csv_line,newline); + + // if user has not passed a separator manually // then attempt to detect by reading first line std::string sep = boost::trim_copy(separator); if (sep.empty()) @@ -189,6 +204,9 @@ void csv_datasource::parse_csv(T& stream, } } } + + // set back to start + stream.seekg (0, std::ios::beg); typedef boost::escaped_list_separator escape_type; @@ -322,7 +340,7 @@ void csv_datasource::parse_csv(T& stream, if (!has_wkt_field && (!has_lon_field || !has_lat_field) ) { std::ostringstream s; - s << "CSV Plugin: could not detect column headers with the name of 'wkt' or lat/lon - this is required for reading geometry data"; + s << "CSV Plugin: could not detect column headers with the name of wkt ,x/y, or latitude/longitude - this is required for reading geometry data"; throw mapnik::datasource_exception(s.str()); } @@ -373,7 +391,6 @@ void csv_datasource::parse_csv(T& stream, bool parsed_x = false; bool parsed_y = false; bool parsed_wkt = false; - bool first_feature = true; bool skip = false; bool null_geom = false; std::vector collected; @@ -433,7 +450,20 @@ void csv_datasource::parse_csv(T& stream, } else { - std::clog << "could not parse: " << value << "\n"; + std::ostringstream s; + s << "CSV Plugin: expected well known text geometry: could not parse row " + << line_number + << ",column " + << i << " - found: '" + << value << "'"; + if (strict_) + { + throw mapnik::datasource_exception(s.str()); + } + else + { + if (!quiet_) std::clog << s.str() << "\n"; + } } } else @@ -538,11 +568,16 @@ void csv_datasource::parse_csv(T& stream, boost::put(*feature,fld_name,mapnik::value_null()); } // only true strings are this long - else if (value_length > 20) + else if (value_length > 20 + // TODO - clean up this messiness which is here temporarily + // to protect against the improperly working spirit parsing below + || value.find(",") != std::string::npos + || value.find(":") != std::string::npos + || (std::count(value.begin(), value.end(), '-') > 1)) { UnicodeString ustr = tr.transcode(value.c_str()); boost::put(*feature,fld_name,ustr); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); } @@ -557,14 +592,14 @@ void csv_datasource::parse_csv(T& stream, if (value.find(".") != std::string::npos) { boost::put(*feature,fld_name,float_val); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Double)); } else { int val = static_cast(float_val); boost::put(*feature,fld_name,val); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Integer)); } } @@ -573,22 +608,23 @@ void csv_datasource::parse_csv(T& stream, // fallback to normal string UnicodeString ustr = tr.transcode(value.c_str()); boost::put(*feature,fld_name,ustr); - if (first_feature) - desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); + if (!feature_count) + desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); } } else { - if (value == "true") + std::string value_lower = boost::algorithm::to_lower_copy(value); + if (value_lower == "true") { boost::put(*feature,fld_name,true); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean)); } - else if(value == "false") + else if(value_lower == "false") { boost::put(*feature,fld_name,false); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::Boolean)); } else @@ -596,14 +632,12 @@ void csv_datasource::parse_csv(T& stream, // fallback to normal string UnicodeString ustr = tr.transcode(value.c_str()); boost::put(*feature,fld_name,ustr); - if (first_feature) + if (!feature_count) desc_.add_descriptor(mapnik::attribute_descriptor(fld_name,mapnik::String)); } } } - first_feature = false; - if (skip) { ++line_number; From 14c29379bfdc632e7ea031feacd297a3c3634510 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 18:22:02 -0700 Subject: [PATCH 10/33] make csv plugin compile by default so we can start using easily for testing mapnik more broadly (avoiding ogr dependency for json reading) --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index 320331a63..1106cf763 100644 --- a/SConstruct +++ b/SConstruct @@ -102,7 +102,7 @@ PLUGINS = { # plugins with external dependencies # plugins without external dependencies requiring CheckLibWithHeader... 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, + 'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, From 90154e0a1a481227ae1819f94587ebaa0f82c413 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 19:27:23 -0700 Subject: [PATCH 11/33] csv plugin: also detect lat/lon/long field names as likely geometry columns --- plugins/input/csv/csv_datasource.cpp | 19 ++++++++++++++----- tests/data/csv/latitude_longitude.csv | 2 ++ .../data/csv/latitude_longitude_substring.csv | 2 ++ tests/data/csv/lon_lat.csv | 2 ++ tests/data/csv/long_lat.csv | 2 ++ tests/data/csv/x_y.csv | 2 ++ 6 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 tests/data/csv/latitude_longitude.csv create mode 100644 tests/data/csv/latitude_longitude_substring.csv create mode 100644 tests/data/csv/lon_lat.csv create mode 100644 tests/data/csv/long_lat.csv create mode 100644 tests/data/csv/x_y.csv diff --git a/plugins/input/csv/csv_datasource.cpp b/plugins/input/csv/csv_datasource.cpp index c1a8a0b4a..88a3cad62 100644 --- a/plugins/input/csv/csv_datasource.cpp +++ b/plugins/input/csv/csv_datasource.cpp @@ -115,7 +115,6 @@ void csv_datasource::bind() const parse_csv(in,escape_, separator_, quote_); in.close(); } - is_bound_ = true; } @@ -257,12 +256,17 @@ void csv_datasource::parse_csv(T& stream, wkt_idx = idx; has_wkt_field = true; } - if (lower_val == "x" || (lower_val.find("longitude") != std::string::npos)) + if (lower_val == "x" + || lower_val == "lon" + || lower_val == "long" + || (lower_val.find("longitude") != std::string::npos)) { lon_idx = idx; has_lon_field = true; } - if (lower_val == "y" || (lower_val.find("latitude") != std::string::npos)) + if (lower_val == "y" + || lower_val == "lat" + || (lower_val.find("latitude") != std::string::npos)) { lat_idx = idx; has_lat_field = true; @@ -311,12 +315,17 @@ void csv_datasource::parse_csv(T& stream, wkt_idx = idx; has_wkt_field = true; } - if (lower_val == "x" || (lower_val.find("longitude") != std::string::npos)) + if (lower_val == "x" + || lower_val == "lon" + || lower_val == "long" + || (lower_val.find("longitude") != std::string::npos)) { lon_idx = idx; has_lon_field = true; } - if (lower_val == "y" || (lower_val.find("latitude") != std::string::npos)) + if (lower_val == "y" + || lower_val == "lat" + || (lower_val.find("latitude") != std::string::npos)) { lat_idx = idx; has_lat_field = true; diff --git a/tests/data/csv/latitude_longitude.csv b/tests/data/csv/latitude_longitude.csv new file mode 100644 index 000000000..109e3464e --- /dev/null +++ b/tests/data/csv/latitude_longitude.csv @@ -0,0 +1,2 @@ +latitude,longitude +0,0 \ No newline at end of file diff --git a/tests/data/csv/latitude_longitude_substring.csv b/tests/data/csv/latitude_longitude_substring.csv new file mode 100644 index 000000000..4cd85d82d --- /dev/null +++ b/tests/data/csv/latitude_longitude_substring.csv @@ -0,0 +1,2 @@ +this_is_longitude_yo,this_is_latitude_yo +0,0 \ No newline at end of file diff --git a/tests/data/csv/lon_lat.csv b/tests/data/csv/lon_lat.csv new file mode 100644 index 000000000..5ce2fc929 --- /dev/null +++ b/tests/data/csv/lon_lat.csv @@ -0,0 +1,2 @@ +lon,lat +0,0 \ No newline at end of file diff --git a/tests/data/csv/long_lat.csv b/tests/data/csv/long_lat.csv new file mode 100644 index 000000000..77be88561 --- /dev/null +++ b/tests/data/csv/long_lat.csv @@ -0,0 +1,2 @@ +long,lat +0,0 \ No newline at end of file diff --git a/tests/data/csv/x_y.csv b/tests/data/csv/x_y.csv new file mode 100644 index 000000000..d436ff3b7 --- /dev/null +++ b/tests/data/csv/x_y.csv @@ -0,0 +1,2 @@ +x,y +0,0 \ No newline at end of file From 1b1822a65aba005df9a13445b9d60319cf5dd0ec Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Tue, 18 Oct 2011 20:50:54 -0700 Subject: [PATCH 12/33] remove duplicate entry for csv plugin in build list --- SConstruct | 1 - 1 file changed, 1 deletion(-) diff --git a/SConstruct b/SConstruct index 1106cf763..d84fb1bd4 100644 --- a/SConstruct +++ b/SConstruct @@ -104,7 +104,6 @@ PLUGINS = { # plugins with external dependencies 'shape': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'csv': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'raster': {'default':True,'path':None,'inc':None,'lib':None,'lang':'C++'}, - 'csv': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, 'kismet': {'default':False,'path':None,'inc':None,'lib':None,'lang':'C++'}, } From 0de5fdf622d5470ae3550e58014d6ae50e7d833e Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 19 Oct 2011 13:23:22 +0200 Subject: [PATCH 13/33] - cleaned up readability of occi featureset by using named const variables --- plugins/input/occi/occi_featureset.cpp | 45 +++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/plugins/input/occi/occi_featureset.cpp b/plugins/input/occi/occi_featureset.cpp index 1eb89a68c..9d850b1e7 100644 --- a/plugins/input/occi/occi_featureset.cpp +++ b/plugins/input/occi/occi_featureset.cpp @@ -241,14 +241,18 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, { if (ordinates_size >= dimensions) { + const bool is_single_geom = true; + const bool is_point_type = false; + const bool multiple_geoms = false; + convert_ordinates (feature, mapnik::LineString, elem_info, ordinates, dimensions, - true, // is_single_geom - false, // is_point_type - false); // multiple_geometries + is_single_geom, + is_point_type, + multiple_geoms); } } break; @@ -256,14 +260,18 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, { if (ordinates_size >= dimensions) { + const bool is_single_geom = true; + const bool is_point_type = false; + const bool multiple_geoms = false; + convert_ordinates (feature, mapnik::Polygon, elem_info, ordinates, dimensions, - true, // is_single_geom - false, // is_point_type - false); // multiple_geometries + is_single_geom, + is_point_type, + multiple_geoms); } } break; @@ -273,6 +281,7 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, { const bool is_single_geom = false; const bool is_point_type = true; + const bool multiple_geoms = true; // Todo - force using true as multiple_geometries until we have proper multipoint handling // http://trac.mapnik.org/ticket/458 @@ -282,9 +291,9 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, elem_info, ordinates, dimensions, - false, // is_single_geom - true, // is_point_type - true); // multiple_geometries + is_single_geom, + is_point_type, + multiple_geoms); } } break; @@ -292,13 +301,16 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, { if (ordinates_size >= dimensions) { + const bool is_single_geom = false; + const bool is_point_type = false; + convert_ordinates (feature, mapnik::LineString, elem_info, ordinates, dimensions, - false, // is_single_geom - false, // is_point_type + is_single_geom, + is_point_type, multiple_geometries); } @@ -308,13 +320,16 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, { if (ordinates_size >= dimensions) { + const bool is_single_geom = false; + const bool is_point_type = false; + convert_ordinates (feature, mapnik::Polygon, elem_info, ordinates, dimensions, - false, // is_single_geom - false, // is_point_type + is_single_geom, + is_point_type, multiple_geometries); } @@ -332,8 +347,8 @@ void occi_featureset::convert_geometry (SDOGeometry* geom, feature_ptr feature, elem_info, ordinates, dimensions, - false, // is_single_geom, - false, // is_point_type + is_single_geom, + is_point_type, multiple_geometries); } } From fa69cf13122320d5194386690b5074b128d3b7ee Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 19 Oct 2011 13:24:32 +0200 Subject: [PATCH 14/33] - improved linux project file (added bindings too) --- workspace/bindings.pri | 49 ++++++++++++++++++++++++++++++++++++++++++ workspace/mapnik.pro | 7 +++++- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 workspace/bindings.pri diff --git a/workspace/bindings.pri b/workspace/bindings.pri new file mode 100644 index 000000000..acd4f6753 --- /dev/null +++ b/workspace/bindings.pri @@ -0,0 +1,49 @@ + +HEADERS += \ + $$PWD/../bindings/python/mapnik_enumeration.hpp \ + $$PWD/../bindings/python/mapnik_svg.hpp \ + $$PWD/../bindings/python/mapnik_value_converter.hpp \ + $$PWD/../bindings/python/python_grid_utils.hpp \ + $$PWD/../bindings/python/python_optional.hpp + +SOURCES += \ + $$PWD/../bindings/python/mapnik_color.cpp \ + $$PWD/../bindings/python/mapnik_coord.cpp \ + $$PWD/../bindings/python/mapnik_datasource.cpp \ + $$PWD/../bindings/python/mapnik_datasource_cache.cpp \ + $$PWD/../bindings/python/mapnik_envelope.cpp \ + $$PWD/../bindings/python/mapnik_expression.cpp \ + $$PWD/../bindings/python/mapnik_feature.cpp \ + $$PWD/../bindings/python/mapnik_featureset.cpp \ + $$PWD/../bindings/python/mapnik_font_engine.cpp \ + $$PWD/../bindings/python/mapnik_geometry.cpp \ + $$PWD/../bindings/python/mapnik_glyph_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_grid.cpp \ + $$PWD/../bindings/python/mapnik_grid_view.cpp \ + $$PWD/../bindings/python/mapnik_image.cpp \ + $$PWD/../bindings/python/mapnik_image_view.cpp \ + $$PWD/../bindings/python/mapnik_inmem_metawriter.cpp \ + $$PWD/../bindings/python/mapnik_layer.cpp \ + $$PWD/../bindings/python/mapnik_line_pattern_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_line_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_map.cpp \ + $$PWD/../bindings/python/mapnik_markers_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_palette.cpp \ + $$PWD/../bindings/python/mapnik_parameters.cpp \ + $$PWD/../bindings/python/mapnik_point_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_polygon_pattern_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_polygon_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_proj_transform.cpp \ + $$PWD/../bindings/python/mapnik_projection.cpp \ + $$PWD/../bindings/python/mapnik_python.cpp \ + $$PWD/../bindings/python/mapnik_query.cpp \ + $$PWD/../bindings/python/mapnik_raster_colorizer.cpp \ + $$PWD/../bindings/python/mapnik_raster_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_rule.cpp \ + $$PWD/../bindings/python/mapnik_shield_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_stroke.cpp \ + $$PWD/../bindings/python/mapnik_style.cpp \ + $$PWD/../bindings/python/mapnik_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_text_symbolizer.cpp \ + $$PWD/../bindings/python/mapnik_view_transform.cpp \ + $$PWD/../bindings/python/python_cairo.cpp diff --git a/workspace/mapnik.pro b/workspace/mapnik.pro index 5672de642..60a86e6be 100644 --- a/workspace/mapnik.pro +++ b/workspace/mapnik.pro @@ -201,8 +201,13 @@ SOURCES += \ ../src/unicode.cpp \ ../src/warp.cpp \ ../src/wkb.cpp - + +OTHER_FILES += \ + ../SConstruct \ + ../config.py + include(plugins.pri) +include(bindings.pri) unix { DEFINES += LINUX=1 From f9c65b8a91bb2893d321368b8bd959bab7cb6578 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 19 Oct 2011 13:25:08 +0200 Subject: [PATCH 15/33] - avoid using temporary pointer in sqlite blob/text resultsets --- plugins/input/sqlite/sqlite_types.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/input/sqlite/sqlite_types.hpp b/plugins/input/sqlite/sqlite_types.hpp index 7659bcff1..49ae59f1e 100644 --- a/plugins/input/sqlite/sqlite_types.hpp +++ b/plugins/input/sqlite/sqlite_types.hpp @@ -135,9 +135,8 @@ public: const char* column_text (int col, int& len) { - const char* text = (const char*) sqlite3_column_text (stmt_, col); len = sqlite3_column_bytes (stmt_, col); - return text; + return (const char*) sqlite3_column_text (stmt_, col); } const char* column_text (int col) @@ -147,9 +146,8 @@ public: const void* column_blob (int col, int& bytes) { - const char* blob = (const char*) sqlite3_column_blob (stmt_, col); bytes = sqlite3_column_bytes (stmt_, col); - return blob; + return (const char*) sqlite3_column_blob (stmt_, col); } sqlite3_stmt* get_statement() From 02fb7740c52cc17f23978fddc51bff6854434496 Mon Sep 17 00:00:00 2001 From: kunitoki Date: Wed, 19 Oct 2011 13:25:42 +0200 Subject: [PATCH 16/33] - added initial support for 25D geometries in WKB (dropping Z) - works ok for spatialite XYZ geometries 3D --- src/wkb.cpp | 425 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 346 insertions(+), 79 deletions(-) diff --git a/src/wkb.cpp b/src/wkb.cpp index d3c067fa0..2e434f990 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -29,6 +29,7 @@ // boost #include +#include namespace mapnik { @@ -56,9 +57,16 @@ public: wkbMultiPoint=4, wkbMultiLineString=5, wkbMultiPolygon=6, - wkbGeometryCollection=7 + wkbGeometryCollection=7, + wkbPointZ=1001, + wkbLineStringZ=1002, + wkbPolygonZ=1003, + wkbMultiPointZ=1004, + wkbMultiLineStringZ=1005, + wkbMultiPolygonZ=1006, + wkbGeometryCollectionZ=1007 }; - + wkb_reader(const char* wkb,unsigned size, wkbFormat format) : wkb_(wkb), size_(size), @@ -68,10 +76,9 @@ public: // try to determine WKB format automatically if (format_ == wkbAuto) { - if (size > 38 - && wkb_[0] == 0x00 - && (wkb_[1] == 0x00 || wkb_[1] == 0x01) - && wkb_[38] == 0x7C) + if (size >= 44 + && (unsigned char)(wkb_[0]) == (unsigned char)(0x00) + && (unsigned char)(wkb_[38]) == (unsigned char)(0x7C)) { format_ = wkbSpatiaLite; } @@ -86,19 +93,25 @@ public: case wkbSpatiaLite: byteOrder_ = (wkbByteOrder) wkb_[1]; pos_ = 39; +#ifdef MAPNIK_DEBUG_WKB + std::clog << "wkb_reader: format is wkbSpatiaLite" << std::endl; +#endif break; case wkbGeneric: default: byteOrder_ = (wkbByteOrder) wkb_[0]; pos_ = 1; +#ifdef MAPNIK_DEBUG_WKB + std::clog << "wkb_reader: format is wkbGeneric" << std::endl; +#endif break; } #ifndef MAPNIK_BIG_ENDIAN - needSwap_=byteOrder_?wkbXDR:wkbNDR; + needSwap_ = byteOrder_ ? wkbXDR : wkbNDR; #else - needSwap_=byteOrder_?wkbNDR:wkbXDR; + needSwap_ = byteOrder_ ? wkbNDR : wkbXDR; #endif } @@ -106,7 +119,13 @@ public: void read_multi(boost::ptr_vector & paths) { - int type=read_integer(); + int type = read_integer(); + +#ifdef MAPNIK_DEBUG_WKB + std::clog << "wkb_reader: read_multi " + << wkb_geometry_type_string(type) << " " << type << std::endl; +#endif + switch (type) { case wkbPoint: @@ -130,6 +149,27 @@ public: case wkbGeometryCollection: read_collection(paths); break; + case wkbPointZ: + read_point_xyz(paths); + break; + case wkbLineStringZ: + read_linestring_xyz(paths); + break; + case wkbPolygonZ: + read_polygon_xyz(paths); + break; + case wkbMultiPointZ: + read_multipoint_xyz(paths); + break; + case wkbMultiLineStringZ: + read_multilinestring_xyz(paths); + break; + case wkbMultiPolygonZ: + read_multipolygon_xyz(paths); + break; + case wkbGeometryCollectionZ: + read_collection(paths); + break; default: break; } @@ -137,7 +177,12 @@ public: void read(boost::ptr_vector & paths) { - int type=read_integer(); + int type = read_integer(); + +#ifdef MAPNIK_DEBUG_WKB + std::clog << "wkb_reader: read " << wkb_geometry_type_string(type) << " " << type << std::endl; +#endif + switch (type) { case wkbPoint: @@ -161,6 +206,27 @@ public: case wkbGeometryCollection: read_collection_2(paths); break; + case wkbPointZ: + read_point_xyz(paths); + break; + case wkbLineStringZ: + read_linestring_xyz(paths); + break; + case wkbPolygonZ: + read_polygon_xyz(paths); + break; + case wkbMultiPointZ: + read_multipoint_xyz_2(paths); + break; + case wkbMultiLineStringZ: + read_multilinestring_xyz_2(paths); + break; + case wkbMultiPolygonZ: + read_multipolygon_xyz_2(paths); + break; + case wkbGeometryCollectionZ: + read_collection_2(paths); + break; default: break; } @@ -173,13 +239,13 @@ private: boost::int32_t n; if (needSwap_) { - read_int32_xdr(wkb_+pos_,n); + read_int32_xdr(wkb_ + pos_, n); } else { - read_int32_ndr(wkb_+pos_,n); + read_int32_ndr(wkb_ + pos_, n); } - pos_+=4; + pos_ += 4; return n; } @@ -195,127 +261,236 @@ private: { read_double_ndr(wkb_ + pos_, d); } - pos_+=8; + pos_ += 8; return d; } void read_coords(CoordinateArray& ar) { - int size=sizeof(coord)*ar.size(); - if (!needSwap_) + if (! needSwap_) { - std::memcpy(&ar[0],wkb_+pos_,size); - pos_+=size; + for (unsigned i = 0; i < ar.size(); ++i) + { + read_double_ndr(wkb_ + pos_, ar[i].x); + read_double_ndr(wkb_ + pos_ + 8, ar[i].y); + pos_ += 16; // skip XY + } } else { for (unsigned i=0;i & paths) { - geometry_type * pt = new geometry_type(Point); + geometry_type* pt = new geometry_type(Point); double x = read_double(); double y = read_double(); - pt->move_to(x,y); + pt->move_to(x, y); paths.push_back(pt); } void read_multipoint(boost::ptr_vector & paths) { int num_points = read_integer(); - for (int i=0;i & paths) { - geometry_type * pt = new geometry_type(MultiPoint); + geometry_type* pt = new geometry_type(MultiPoint); int num_points = read_integer(); - for (int i=0;imove_to(x,y); + pt->move_to(x, y); } paths.push_back(pt); } - + + void read_point_xyz(boost::ptr_vector & paths) + { + geometry_type* pt = new geometry_type(Point); + double x = read_double(); + double y = read_double(); + pos_ += 8; // double z = read_double(); + pt->move_to(x, y); + paths.push_back(pt); + } + + void read_multipoint_xyz(boost::ptr_vector & paths) + { + int num_points = read_integer(); + for (int i = 0; i < num_points; ++i) + { + pos_ += 5; + read_point_xyz(paths); + } + } + + void read_multipoint_xyz_2(boost::ptr_vector & paths) + { + geometry_type* pt = new geometry_type(MultiPoint); + int num_points = read_integer(); + for (int i = 0; i < num_points; ++i) + { + pos_ += 5; + double x = read_double(); + double y = read_double(); + pos_ += 8; // double z = read_double(); + pt->move_to(x, y); + } + paths.push_back(pt); + } + + void read_linestring(boost::ptr_vector & paths) { - geometry_type * line = new geometry_type(LineString); - int num_points=read_integer(); + geometry_type* line = new geometry_type(LineString); + int num_points = read_integer(); CoordinateArray ar(num_points); read_coords(ar); line->set_capacity(num_points); - line->move_to(ar[0].x,ar[0].y); - for (int i=1;imove_to(ar[0].x, ar[0].y); + for (int i = 1; i < num_points; ++i) { - line->line_to(ar[i].x,ar[i].y); + line->line_to(ar[i].x, ar[i].y); } paths.push_back(line); } void read_multilinestring(boost::ptr_vector & paths) { - int num_lines=read_integer(); - for (int i=0;i & paths) { - geometry_type * line = new geometry_type(MultiLineString); - int num_lines=read_integer(); + geometry_type* line = new geometry_type(MultiLineString); + int num_lines = read_integer(); unsigned capacity = 0; - for (int i=0;iset_capacity(capacity); - line->move_to(ar[0].x,ar[0].y); - for (int j=1;jmove_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) { - line->line_to(ar[j].x,ar[j].y); + line->line_to(ar[j].x, ar[j].y); } } paths.push_back(line); } - + + void read_linestring_xyz(boost::ptr_vector & paths) + { + geometry_type* line = new geometry_type(LineString); + int num_points = read_integer(); + CoordinateArray ar(num_points); + read_coords_xyz(ar); + line->set_capacity(num_points); + line->move_to(ar[0].x, ar[0].y); + for (int i = 1; i < num_points; ++i) + { + line->line_to(ar[i].x, ar[i].y); + } + paths.push_back(line); + } + + void read_multilinestring_xyz(boost::ptr_vector & paths) + { + int num_lines = read_integer(); + for (int i = 0; i < num_lines; ++i) + { + pos_ += 5; + read_linestring_xyz(paths); + } + } + + void read_multilinestring_xyz_2(boost::ptr_vector & paths) + { + geometry_type* line = new geometry_type(MultiLineString); + int num_lines = read_integer(); + unsigned capacity = 0; + for (int i = 0; i < num_lines; ++i) + { + pos_ += 5; + int num_points = read_integer(); + capacity += num_points; + CoordinateArray ar(num_points); + read_coords_xyz(ar); + line->set_capacity(capacity); + line->move_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) + { + line->line_to(ar[j].x, ar[j].y); + } + } + paths.push_back(line); + } + + void read_polygon(boost::ptr_vector & paths) { - geometry_type * poly = new geometry_type(Polygon); - int num_rings=read_integer(); + geometry_type* poly = new geometry_type(Polygon); + int num_rings = read_integer(); unsigned capacity = 0; - for (int i=0;iset_capacity(capacity); - poly->move_to(ar[0].x,ar[0].y); - for (int j=1;jmove_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) { - poly->line_to(ar[j].x,ar[j].y); + poly->line_to(ar[j].x, ar[j].y); } } paths.push_back(poly); @@ -323,60 +498,148 @@ private: void read_multipolygon(boost::ptr_vector & paths) { - int num_polys=read_integer(); - for (int i=0;i & paths) { - geometry_type * poly = new geometry_type(MultiPolygon); - int num_polys=read_integer(); + geometry_type* poly = new geometry_type(MultiPolygon); + int num_polys = read_integer(); unsigned capacity = 0; - for (int i=0;iset_capacity(capacity); - poly->move_to(ar[0].x,ar[0].y); - for (int j=1;jmove_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) { - poly->line_to(ar[j].x,ar[j].y); + poly->line_to(ar[j].x, ar[j].y); } - poly->line_to(ar[0].x,ar[0].y); + poly->line_to(ar[0].x, ar[0].y); } } paths.push_back(poly); } + void read_polygon_xyz(boost::ptr_vector & paths) + { + geometry_type* poly = new geometry_type(Polygon); + int num_rings = read_integer(); + unsigned capacity = 0; + for (int i = 0; i < num_rings; ++i) + { + int num_points = read_integer(); + capacity += num_points; + CoordinateArray ar(num_points); + read_coords_xyz(ar); + poly->set_capacity(capacity); + poly->move_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) + { + poly->line_to(ar[j].x, ar[j].y); + } + } + paths.push_back(poly); + } + + void read_multipolygon_xyz(boost::ptr_vector & paths) + { + int num_polys = read_integer(); + for (int i = 0; i < num_polys; ++i) + { + pos_ += 5; + read_polygon_xyz(paths); + } + } + + void read_multipolygon_xyz_2(boost::ptr_vector & paths) + { + geometry_type* poly = new geometry_type(MultiPolygon); + int num_polys = read_integer(); + unsigned capacity = 0; + for (int i = 0; i < num_polys; ++i) + { + pos_ += 5; + int num_rings = read_integer(); + for (int r = 0; r < num_rings; ++r) + { + int num_points = read_integer(); + capacity += num_points; + CoordinateArray ar(num_points); + read_coords_xyz(ar); + poly->set_capacity(capacity); + poly->move_to(ar[0].x, ar[0].y); + for (int j = 1; j < num_points; ++j) + { + poly->line_to(ar[j].x, ar[j].y); + } + poly->line_to(ar[0].x, ar[0].y); + } + } + paths.push_back(poly); + } + + void read_collection(boost::ptr_vector & paths) { - int num_geometries=read_integer(); - for (int i=0;i & paths) { - int num_geometries=read_integer(); - for (int i=0;i& paths, @@ -385,10 +648,14 @@ void geometry_utils::from_wkb (boost::ptr_vector& paths, bool multiple_geometries, wkbFormat format) { - wkb_reader reader(wkb,size,format); + wkb_reader reader(wkb, size, format); if (multiple_geometries) + { return reader.read_multi(paths); + } else + { return reader.read(paths); + } } } From b0bd5b769d28432957f01fb40ea31f29091f8d86 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 14:45:17 +0100 Subject: [PATCH 17/33] ignore emacs generated tmp files (*~) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ec4575b6f..e64ea97ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*~ *.o *.pyc *.os From 9a37fee17db23e4d4ee2ac370e542b904490209c Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 15:14:01 +0100 Subject: [PATCH 18/33] remove operator-= from box2d --- include/mapnik/box2d.hpp | 6 ++---- src/box2d.cpp | 8 -------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/include/mapnik/box2d.hpp b/include/mapnik/box2d.hpp index edb4a85c2..b9e21ad35 100644 --- a/include/mapnik/box2d.hpp +++ b/include/mapnik/box2d.hpp @@ -41,9 +41,8 @@ namespace mapnik { template class MAPNIK_DECL box2d : boost::equality_comparable , boost::addable, - boost::subtractable, - boost::dividable2, T, - boost::multipliable2, T > > > > > + boost::dividable2, T, + boost::multipliable2, T > > > > { public: typedef box2d box2d_type; @@ -86,7 +85,6 @@ public: // define some operators box2d_type& operator+=(box2d_type const& other); - box2d_type& operator-=(box2d_type const& other); box2d_type& operator*=(T); box2d_type& operator/=(T); T operator[](int index) const; diff --git a/src/box2d.cpp b/src/box2d.cpp index b4a069095..4998994cc 100644 --- a/src/box2d.cpp +++ b/src/box2d.cpp @@ -384,14 +384,6 @@ box2d& box2d::operator+=(box2d const& other) return *this; } -/* -template -box2d& box2d::operator-=(box2d const& other) -{ - // not sure what to do here. intersect? - return *this; -} -*/ template box2d& box2d::operator*=(T t) From d40f5d7d5942bb86ccec72e9c6adaf2f63ca2739 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 15:17:48 +0100 Subject: [PATCH 19/33] add round() and M_PI support for windows builds --- include/mapnik/global.hpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/mapnik/global.hpp b/include/mapnik/global.hpp index 83e87db7e..55eb6f1b1 100644 --- a/include/mapnik/global.hpp +++ b/include/mapnik/global.hpp @@ -166,8 +166,21 @@ inline int rint( double val) { return int(floor(val + 0.5)); } + +inline double round (double val) +{ + return floor(val); +} + +#define _USE_MATH_DEFINES +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + #endif } + + #endif //GLOBAL_HPP From 49cb8c736819bc5fc6441b897ced1cc2a958a161 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 15:19:55 +0100 Subject: [PATCH 20/33] qualify attribute -> mapnik::attribute (vc10) --- include/mapnik/expression_grammar.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/mapnik/expression_grammar.hpp b/include/mapnik/expression_grammar.hpp index bfb8a22d6..8f6a4f1e2 100644 --- a/include/mapnik/expression_grammar.hpp +++ b/include/mapnik/expression_grammar.hpp @@ -50,6 +50,7 @@ namespace mapnik { +using namespace boost; namespace qi = boost::spirit::qi; namespace standard_wide = boost::spirit::standard_wide; using standard_wide::space_type; @@ -217,7 +218,7 @@ struct expression_grammar : qi::grammar | lit("false") [_val = false] | lit("null") [_val = value_null() ] | ustring [_val = unicode_(_1) ] - | attr [_val = construct( _1 ) ] + | attr [_val = construct( _1 ) ] | '(' >> expr [_val = _1 ] >> ')' ; From 9088d7bbc84ef7f352f73e44ed540197e22e0480 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 15:29:24 +0100 Subject: [PATCH 21/33] + various win32 fixes, mainly adding extra namespace qualifiers for vc++10, MAPNIK_DECL ... --- bindings/python/mapnik_geometry.cpp | 2 +- bindings/python/mapnik_grid.cpp | 4 ++-- bindings/python/mapnik_grid_view.cpp | 4 ++-- bindings/python/mapnik_inmem_metawriter.cpp | 2 +- bindings/python/mapnik_rule.cpp | 4 ++-- bindings/python/mapnik_svg.hpp | 2 +- bindings/python/python_grid_utils.hpp | 8 +++---- include/mapnik/feature_type_style.hpp | 2 +- include/mapnik/font_engine_freetype.hpp | 2 +- include/mapnik/grid/grid.hpp | 18 +++++++++------ include/mapnik/grid/grid_view.hpp | 4 +++- include/mapnik/hextree.hpp | 2 +- include/mapnik/image_util.hpp | 23 ++++++++++++++++---- include/mapnik/metawriter_inmem.hpp | 9 ++++---- include/mapnik/palette.hpp | 3 ++- include/mapnik/parse_path.hpp | 3 ++- include/mapnik/path_expression_grammar.hpp | 4 ++-- include/mapnik/raster_colorizer.hpp | 4 ++-- include/mapnik/svg/svg_path_commands.hpp | 5 +++++ include/mapnik/svg/svg_path_parser.hpp | 7 +++--- include/mapnik/svg/svg_transform_grammar.hpp | 4 ++++ include/mapnik/text_placements.hpp | 5 +++-- include/mapnik/text_symbolizer.hpp | 6 ++--- include/mapnik/value.hpp | 16 ++++++-------- include/mapnik/wkt/wkt_factory.hpp | 7 ++++-- src/grid/grid_renderer.cpp | 2 ++ src/load_map.cpp | 6 ++--- src/proj_transform.cpp | 1 + src/raster_colorizer.cpp | 9 +++++--- src/svg_transform_parser.cpp | 6 +++-- src/text_placements.cpp | 4 ++-- 31 files changed, 110 insertions(+), 68 deletions(-) diff --git a/bindings/python/mapnik_geometry.cpp b/bindings/python/mapnik_geometry.cpp index 0883c2539..c1a1c871e 100644 --- a/bindings/python/mapnik_geometry.cpp +++ b/bindings/python/mapnik_geometry.cpp @@ -49,7 +49,7 @@ geometry_type const& getitem_impl(path_type & p, int key) void from_wkt_impl(path_type& p, std::string const& wkt) { - bool result = mapnik::from_wkt(wkt, p); + bool result = mapnik::from_wkt(wkt , p); if (!result) throw std::runtime_error("Failed to parse WKT"); } diff --git a/bindings/python/mapnik_grid.cpp b/bindings/python/mapnik_grid.cpp index 0a5f3b80a..4906c5460 100644 --- a/bindings/python/mapnik_grid.cpp +++ b/bindings/python/mapnik_grid.cpp @@ -46,7 +46,7 @@ void export_grid() "Grid", "This class represents a feature hitgrid.", init( - ( arg("width"),arg("height"),arg("key")="__id__",arg("resolution")=1 ), + ( boost::python::arg("width"), boost::python::arg("height"),boost::python::arg("key")="__id__", boost::python::arg("resolution")=1 ), "Create a mapnik.Grid object\n" )) .def("painted",&painted) @@ -54,7 +54,7 @@ void export_grid() .def("height",&mapnik::grid::height) .def("view",&mapnik::grid::get_view) .def("encode",encode, - ( arg("encoding")="utf",arg("features")=true,arg("resolution")=4 ), + ( boost::python::arg("encoding")="utf", boost::python::arg("features")=true,boost::python::arg("resolution")=4 ), "Encode the grid as as optimized json\n" ) .add_property("key", diff --git a/bindings/python/mapnik_grid_view.cpp b/bindings/python/mapnik_grid_view.cpp index 88c35d78b..6998f81f3 100644 --- a/bindings/python/mapnik_grid_view.cpp +++ b/bindings/python/mapnik_grid_view.cpp @@ -45,8 +45,8 @@ void export_grid_view() .def("width",&mapnik::grid_view::width) .def("height",&mapnik::grid_view::height) .def("encode",encode, - ( arg("encoding")="utf",arg("add_features")=true,arg("resolution")=4 ), - "Encode the grid as as optimized json\n" + ( boost::python::arg("encoding")="utf",boost::python::arg("add_features")=true,boost::python::arg("resolution")=4 ), + "Encode the grid as as optimized json\n" ) ; } diff --git a/bindings/python/mapnik_inmem_metawriter.cpp b/bindings/python/mapnik_inmem_metawriter.cpp index 70009b079..d0329ee6b 100644 --- a/bindings/python/mapnik_inmem_metawriter.cpp +++ b/bindings/python/mapnik_inmem_metawriter.cpp @@ -35,7 +35,7 @@ using mapnik::metawriter_inmem_ptr; namespace { std::map::const_iterator mapnik_value_map_begin(const std::map &m) { - return m.begin(); + return m.begin(); } std::map::const_iterator diff --git a/bindings/python/mapnik_rule.cpp b/bindings/python/mapnik_rule.cpp index 67912f1c3..3a2ec50ae 100644 --- a/bindings/python/mapnik_rule.cpp +++ b/bindings/python/mapnik_rule.cpp @@ -148,8 +148,8 @@ struct rule_pickle_suite : boost::python::pickle_suite extract_symbolizer serializer( r ); for (int i=0;i(syms[i]); - boost::apply_visitor( serializer, symbol ); + //symbolizer symbol = extract(syms[i]); + //boost::apply_visitor( serializer, symbol ); } } diff --git a/bindings/python/mapnik_svg.hpp b/bindings/python/mapnik_svg.hpp index 3fb8ef3f2..b0834296f 100644 --- a/bindings/python/mapnik_svg.hpp +++ b/bindings/python/mapnik_svg.hpp @@ -43,7 +43,7 @@ template void set_svg_transform(T& symbolizer, std::string const& transform_wkt) { agg::trans_affine tr; - if (!mapnik::svg::parse_transform(transform_wkt, tr)) + if (!mapnik::svg::parse_transform(transform_wkt.c_str(), tr)) { std::stringstream ss; ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'"; diff --git a/bindings/python/python_grid_utils.hpp b/bindings/python/python_grid_utils.hpp index ee78f2cab..dd9d8ac15 100644 --- a/bindings/python/python_grid_utils.hpp +++ b/bindings/python/python_grid_utils.hpp @@ -50,12 +50,12 @@ static void grid2utf(T const& grid_type, typename T::key_type::const_iterator key_pos; typename T::feature_key_type::const_iterator feature_pos; // start counting at utf8 codepoint 32, aka space character - uint16_t codepoint = 32; + boost::uint16_t codepoint = 32; unsigned array_size = data.width(); for (unsigned y = 0; y < data.height(); ++y) { - uint16_t idx = 0; + boost::uint16_t idx = 0; boost::scoped_array line(new Py_UNICODE[array_size]); typename T::value_type const* row = data.getRow(y); for (unsigned x = 0; x < data.width(); ++x) @@ -103,13 +103,13 @@ static void grid2utf(T const& grid_type, typename T::key_type::const_iterator key_pos; typename T::feature_key_type::const_iterator feature_pos; // start counting at utf8 codepoint 32, aka space character - uint16_t codepoint = 32; + boost::uint16_t codepoint = 32; // TODO - use double? unsigned array_size = static_cast(grid_type.width()/resolution); for (unsigned y = 0; y < grid_type.height(); y=y+resolution) { - uint16_t idx = 0; + boost::uint16_t idx = 0; boost::scoped_array line(new Py_UNICODE[array_size]); mapnik::grid::value_type const* row = grid_type.getRow(y); for (unsigned x = 0; x < grid_type.width(); x=x+resolution) diff --git a/include/mapnik/feature_type_style.hpp b/include/mapnik/feature_type_style.hpp index d4a428778..829d36c82 100644 --- a/include/mapnik/feature_type_style.hpp +++ b/include/mapnik/feature_type_style.hpp @@ -43,7 +43,7 @@ enum filter_mode_enum { DEFINE_ENUM( filter_mode_e, filter_mode_enum ); typedef std::vector rules; -class feature_type_style +class MAPNIK_DECL feature_type_style { private: rules rules_; diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index efaadf7a2..eaa464ace 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -200,7 +200,7 @@ public: void init(double radius) { - FT_Stroker_Set(s_,radius * (1<<6), + FT_Stroker_Set(s_, (FT_Fixed) radius * (1<<6), FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0); diff --git a/include/mapnik/grid/grid.hpp b/include/mapnik/grid/grid.hpp index 8951d934e..801422bfd 100644 --- a/include/mapnik/grid/grid.hpp +++ b/include/mapnik/grid/grid.hpp @@ -24,6 +24,7 @@ #define MAPNIK_GRID_HPP // mapnik +#include #include #include #include @@ -31,6 +32,9 @@ #include #include +// boost +#include + // stl #include #include @@ -95,17 +99,17 @@ public: ~hit_grid() {} - void painted(bool painted) + inline void painted(bool painted) { painted_ = painted; } - bool painted() const + inline bool painted() const { return painted_; } - void add_feature(mapnik::Feature const& feature) + inline void add_feature(mapnik::Feature const& feature) { // copies feature props @@ -152,12 +156,12 @@ public: } } - void add_property_name(std::string const& name) + inline void add_property_name(std::string const& name) { names_.insert(name); } - std::set property_names() const + inline std::set const& property_names() const { return names_; } @@ -275,7 +279,7 @@ public: inline void blendPixel(value_type feature_id,int x,int y,unsigned int rgba1,int t) { - blendPixel2(x,y,rgba1,t,1.0); // do not change opacity + blendPixel2(feature_id ,x,y,rgba1,t,1.0); // do not change opacity } inline void blendPixel2(value_type feature_id,int x,int y,unsigned int rgba1,int t,double opacity) @@ -331,7 +335,7 @@ public: }; -typedef hit_grid grid; +typedef MAPNIK_DECL hit_grid grid; } #endif //MAPNIK_GRID_HPP diff --git a/include/mapnik/grid/grid_view.hpp b/include/mapnik/grid/grid_view.hpp index b09d274fe..e5cdee823 100644 --- a/include/mapnik/grid/grid_view.hpp +++ b/include/mapnik/grid/grid_view.hpp @@ -30,6 +30,8 @@ #include #include +// boost +#include // stl #include #include @@ -188,7 +190,7 @@ private: feature_type const& features_; }; -typedef hit_grid_view > grid_view; +typedef hit_grid_view > grid_view; } diff --git a/include/mapnik/hextree.hpp b/include/mapnik/hextree.hpp index 3ac09cc04..c9f1265e5 100644 --- a/include/mapnik/hextree.hpp +++ b/include/mapnik/hextree.hpp @@ -434,7 +434,7 @@ private: } tries=0; // ignore leaves and also nodes with small mean error and not excessive number of pixels - if ((cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(long(cur_node->pixel_count)) > 15 + if ((cur_node->reduce_cost / cur_node->pixel_count + 1) * std::log(double(cur_node->pixel_count)) > 15 && cur_node->children_count > 0) { colors_--; diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index e841c98fe..2f8aff77d 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.hpp @@ -255,6 +255,8 @@ inline MAPNIK_DECL std::string save_to_string(image_32 const& image, return save_to_string(image.data(), type, palette); } +/////////////////////////////////////////////////////////////////////////// + #ifdef _MSC_VER template MAPNIK_DECL void save_to_file(image_data_32 const&, std::string const&, @@ -263,18 +265,31 @@ template MAPNIK_DECL void save_to_file(image_data_32 const&, template MAPNIK_DECL void save_to_file(image_data_32 const&, std::string const&, rgba_palette const&); -template MAPNIK_DECL std::string save_to_string(image_data_32 const&, - std::string const&, - rgba_palette const&); - + +template MAPNIK_DECL void save_to_file(image_data_32 const&, + std::string const&); + + template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&, std::string const&, rgba_palette const&); +template MAPNIK_DECL void save_to_file > (image_view const&, + std::string const&, + std::string const&); + template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&, rgba_palette const&); + +template MAPNIK_DECL void save_to_file > (image_view const&, + std::string const&); + + +template MAPNIK_DECL std::string save_to_string(image_data_32 const&, + std::string const&, + rgba_palette const&); template MAPNIK_DECL std::string save_to_string > (image_view const&, std::string const&, diff --git a/include/mapnik/metawriter_inmem.hpp b/include/mapnik/metawriter_inmem.hpp index 38bfc32b1..278ffea44 100644 --- a/include/mapnik/metawriter_inmem.hpp +++ b/include/mapnik/metawriter_inmem.hpp @@ -25,6 +25,7 @@ #define METAWRITER_INMEM_HPP // mapnik +#include #include // boost @@ -50,7 +51,7 @@ namespace mapnik { * very common in the rendered image will increase memory usage, especially if * many attributes are also kept. */ -class metawriter_inmem +class MAPNIK_DECL metawriter_inmem : public metawriter, private boost::noncopyable { public: /** @@ -59,8 +60,8 @@ public: * then the name attribute of rendered features referencing this metawriter * will be kept in memory. */ - metawriter_inmem(metawriter_properties dflt_properties); - ~metawriter_inmem(); + metawriter_inmem(metawriter_properties dflt_properties); + ~metawriter_inmem(); virtual void add_box(box2d const& box, Feature const& feature, CoordTransform const& t, @@ -87,7 +88,7 @@ public: * are the intersection of the features' properties and the "kept" * properties of the metawriter. */ - struct meta_instance { + struct MAPNIK_DECL meta_instance { box2d box; std::map properties; }; diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp index e0df13340..18b433b30 100644 --- a/include/mapnik/palette.hpp +++ b/include/mapnik/palette.hpp @@ -26,6 +26,7 @@ // mapnik +#include #include #include @@ -124,7 +125,7 @@ struct rgba typedef boost::unordered_map rgba_hash_table; -class rgba_palette : private boost::noncopyable { +class MAPNIK_DECL rgba_palette : private boost::noncopyable { public: enum palette_type { PALETTE_RGBA = 0, PALETTE_RGB = 1, PALETTE_ACT = 2 }; diff --git a/include/mapnik/parse_path.hpp b/include/mapnik/parse_path.hpp index a1fc8fe60..4434ec2bf 100644 --- a/include/mapnik/parse_path.hpp +++ b/include/mapnik/parse_path.hpp @@ -24,6 +24,7 @@ #define MAPNIK_PARSE_PATH_HPP // mapnik +#include #include #include #include @@ -41,7 +42,7 @@ typedef boost::variant path_component; typedef std::vector path_expression; typedef boost::shared_ptr path_expression_ptr; -path_expression_ptr parse_path(std::string const & str); +MAPNIK_DECL path_expression_ptr parse_path(std::string const & str); template struct path_processor diff --git a/include/mapnik/path_expression_grammar.hpp b/include/mapnik/path_expression_grammar.hpp index 0102aa867..eae2ed7aa 100644 --- a/include/mapnik/path_expression_grammar.hpp +++ b/include/mapnik/path_expression_grammar.hpp @@ -51,7 +51,7 @@ namespace mapnik { - +using namespace boost; namespace qi = boost::spirit::qi; namespace phoenix = boost::phoenix; namespace standard_wide = boost::spirit::standard_wide; @@ -79,7 +79,7 @@ struct path_expression_grammar : qi::grammar> attr [ push_back(_val, construct( _1 )) ] >> ']') + ( '[' >> attr [ push_back(_val, construct( _1 )) ] >> ']') ) ; diff --git a/include/mapnik/raster_colorizer.hpp b/include/mapnik/raster_colorizer.hpp index 8aeb351c2..e0e0796ca 100644 --- a/include/mapnik/raster_colorizer.hpp +++ b/include/mapnik/raster_colorizer.hpp @@ -68,7 +68,7 @@ enum colorizer_mode_enum DEFINE_ENUM( colorizer_mode, colorizer_mode_enum ); //! \brief Structure to represent a stop position. -class colorizer_stop { +class MAPNIK_DECL colorizer_stop { public: //! \brief Constructor @@ -142,7 +142,7 @@ typedef std::vector colorizer_stops; //! \brief Class representing the raster colorizer -class raster_colorizer { +class MAPNIK_DECL raster_colorizer { public: //! \brief Constructor raster_colorizer(colorizer_mode mode = COLORIZER_LINEAR, const color& _color = color(0,0,0,0)); diff --git a/include/mapnik/svg/svg_path_commands.hpp b/include/mapnik/svg/svg_path_commands.hpp index 6d9434d7a..63680bd35 100644 --- a/include/mapnik/svg/svg_path_commands.hpp +++ b/include/mapnik/svg/svg_path_commands.hpp @@ -28,6 +28,11 @@ #include #include +#ifdef _WINDOWS +#define _USE_MATH_DEFINES +#include +#endif + namespace mapnik { namespace svg { using namespace boost::fusion; diff --git a/include/mapnik/svg/svg_path_parser.hpp b/include/mapnik/svg/svg_path_parser.hpp index b21e9394d..d836deffc 100644 --- a/include/mapnik/svg/svg_path_parser.hpp +++ b/include/mapnik/svg/svg_path_parser.hpp @@ -23,6 +23,7 @@ #ifndef SVG_PATH_PARSER_HPP #define SVG_PATH_PARSER_HPP +#include #include namespace mapnik { namespace svg { @@ -34,10 +35,10 @@ template bool parse_points(const char * wkt, PathType & p); template -bool parse_transform(const char * wkt, TransformType & tr); +bool MAPNIK_DECL parse_transform(const char * wkt, TransformType & tr); -template -bool parse_transform(std::string const& wkt, TransformType & tr); +//template +//bool MAPNIK_DECL parse_transform(std::string const& wkt, TransformType & tr); }} diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp index f3c43e7f9..a928b8a92 100644 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ b/include/mapnik/svg/svg_transform_grammar.hpp @@ -35,6 +35,10 @@ #include #include +#ifdef _WINDOWS +#define _USE_MATH_DEFINES +#include +#endif namespace mapnik { namespace svg { diff --git a/include/mapnik/text_placements.hpp b/include/mapnik/text_placements.hpp index e09f4537f..56b0c04de 100644 --- a/include/mapnik/text_placements.hpp +++ b/include/mapnik/text_placements.hpp @@ -23,6 +23,7 @@ #define TEXT_PLACEMENTS_HPP //mapnik +#include #include //stl @@ -154,14 +155,14 @@ typedef boost::shared_ptr text_placements_ptr; class text_placements_info_dummy; -class text_placements_dummy: public text_placements +class MAPNIK_DECL text_placements_dummy: public text_placements { public: text_placement_info_ptr get_placement_info() const; friend class text_placement_info_dummy; }; -class text_placement_info_dummy : public text_placement_info +class MAPNIK_DECL text_placement_info_dummy : public text_placement_info { public: text_placement_info_dummy(text_placements_dummy const* parent) : text_placement_info(parent), diff --git a/include/mapnik/text_symbolizer.hpp b/include/mapnik/text_symbolizer.hpp index f3556cb2a..e322f4516 100644 --- a/include/mapnik/text_symbolizer.hpp +++ b/include/mapnik/text_symbolizer.hpp @@ -47,12 +47,10 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base { text_symbolizer(expression_ptr name, std::string const& face_name, unsigned size, color const& fill, - text_placements_ptr placements = text_placements_ptr( - boost::make_shared()) + text_placements_ptr placements = text_placements_ptr(new text_placements_dummy) ); text_symbolizer(expression_ptr name, unsigned size, color const& fill, - text_placements_ptr placements = text_placements_ptr( - boost::make_shared()) + text_placements_ptr placements = text_placements_ptr(new text_placements_dummy) ); text_symbolizer(text_symbolizer const& rhs); text_symbolizer& operator=(text_symbolizer const& rhs); diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index 95943a165..dfb62ff01 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -25,9 +25,12 @@ #define VALUE_HPP // mapnik +#include #include #include + // boost + #include #include #include @@ -49,9 +52,9 @@ inline void to_utf8(UnicodeString const& input, std::string & target) { if (input.length() == 0) return; - const int32_t BUF_SIZE = 256; + const int BUF_SIZE = 256; char buf [BUF_SIZE]; - int32_t len; + int len; UErrorCode err = U_ZERO_ERROR; u_strToUTF8(buf, BUF_SIZE, &len, input.getBuffer(), input.length(), &err); @@ -106,10 +109,8 @@ struct equals bool operator() (value_null, value_null) const { - // this changed from false to true - see http://trac.mapnik.org/ticket/794 - return true; + return false; } - }; struct not_equals @@ -145,21 +146,18 @@ struct not_equals bool operator() (value_null, value_null) const { - // TODO - needs review http://trac.mapnik.org/ticket/794 return false; } template bool operator() (value_null, const T &) const { - // TODO - needs review http://trac.mapnik.org/ticket/794 return false; } template bool operator() (const T &, value_null) const { - // TODO - needs review http://trac.mapnik.org/ticket/794 return false; } }; @@ -533,7 +531,7 @@ struct to_bool : public boost::static_visitor template bool operator() (T val) const { - return bool(val); + return val > 0 ? true : false; } }; diff --git a/include/mapnik/wkt/wkt_factory.hpp b/include/mapnik/wkt/wkt_factory.hpp index f4c9c2380..cfdb2ba00 100644 --- a/include/mapnik/wkt/wkt_factory.hpp +++ b/include/mapnik/wkt/wkt_factory.hpp @@ -23,13 +23,16 @@ #ifndef MAPNIK_WKT_FACTORY_HPP #define MAPNIK_WKT_FACTORY_HPP -#include +// mapnik +#include #include #include +// stl +#include namespace mapnik { -bool from_wkt(std::string const& wkt, boost::ptr_vector & paths); +MAPNIK_DECL bool from_wkt(std::string const& wkt, boost::ptr_vector & paths); } diff --git a/src/grid/grid_renderer.cpp b/src/grid/grid_renderer.cpp index 6b91cc3ad..cf6c645d9 100644 --- a/src/grid/grid_renderer.cpp +++ b/src/grid/grid_renderer.cpp @@ -173,5 +173,7 @@ void grid_renderer::render_marker(Feature const& feature, unsigned int step, pixmap_.add_feature(feature); } +template class hit_grid; template class grid_renderer; + } diff --git a/src/load_map.cpp b/src/load_map.cpp index d89110563..f31767583 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -896,7 +896,7 @@ void map_parser::parse_point_symbolizer( rule & rule, ptree const & sym ) if (transform_wkt) { agg::trans_affine tr; - if (!mapnik::svg::parse_transform(*transform_wkt,tr)) + if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr)) { std::stringstream ss; ss << "Could not parse transform from '" << transform_wkt @@ -1025,7 +1025,7 @@ void map_parser::parse_markers_symbolizer( rule & rule, ptree const & sym ) if (transform_wkt) { agg::trans_affine tr; - if (!mapnik::svg::parse_transform(*transform_wkt,tr)) + if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr)) { std::stringstream ss; ss << "Could not parse transform from '" << transform_wkt @@ -1671,7 +1671,7 @@ void map_parser::parse_shield_symbolizer( rule & rule, ptree const & sym ) if (transform_wkt) { agg::trans_affine tr; - if (!mapnik::svg::parse_transform(*transform_wkt,tr)) + if (!mapnik::svg::parse_transform((*transform_wkt).c_str(),tr)) { std::stringstream ss; ss << "Could not parse transform from '" << transform_wkt << "', expected string like: 'matrix(1, 0, 0, 1, 0, 0)'"; diff --git a/src/proj_transform.cpp b/src/proj_transform.cpp index 9921fde02..462453deb 100644 --- a/src/proj_transform.cpp +++ b/src/proj_transform.cpp @@ -23,6 +23,7 @@ //$Id$ // mapnik +#include #include #include #include diff --git a/src/raster_colorizer.cpp b/src/raster_colorizer.cpp index 69bb66ab9..603273b1f 100644 --- a/src/raster_colorizer.cpp +++ b/src/raster_colorizer.cpp @@ -118,12 +118,15 @@ void raster_colorizer::colorize(raster_ptr const& raster,const std::map0) + const std::map::const_iterator fi = Props.find("NODATA"); + if (fi != Props.end()) + //if (Props.count("NODATA")>0) { hasNoData = true; - noDataValue = Props.at("NODATA").to_double(); + //noDataValue = Props.at("NODATA").to_double(); + noDataValue = fi->second.to_double(); } - + for (int i=0; i bool parse_transform(std::string const& wkt, TransformType & p) { @@ -53,8 +54,9 @@ bool parse_transform(std::string const& wkt, TransformType & p) iterator_type last = wkt.end(); return qi::phrase_parse(first, last, g, skip_type()); } +*/ -template bool parse_transform(const char*, agg::trans_affine&); -template bool parse_transform(std::string const& , agg::trans_affine&); +template MAPNIK_DECL bool parse_transform(const char*, agg::trans_affine&); +//template bool parse_transform(std::string const& , agg::trans_affine&); }} diff --git a/src/text_placements.cpp b/src/text_placements.cpp index f7f22d5f5..a8eb3574e 100644 --- a/src/text_placements.cpp +++ b/src/text_placements.cpp @@ -168,8 +168,8 @@ void text_placements_simple::set_positions(std::string positions) std::string::iterator first = positions.begin(), last = positions.end(); qi::phrase_parse(first, last, - (direction_name[push_back(ref(direction_), _1)] % ',') >> *(',' >> qi::int_[push_back(ref(text_sizes_), _1)]), - space + (direction_name[push_back(phoenix::ref(direction_), _1)] % ',') >> *(',' >> qi::int_[push_back(phoenix::ref(text_sizes_), _1)]), + space ); if (first != last) { std::cerr << "WARNING: Could not parse text_placement_simple placement string ('" << positions << "').\n"; From 1e70af3c5ad20f61df136c77ffd5ee13e2ce64f0 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 15:32:25 +0100 Subject: [PATCH 22/33] use M_PI from --- include/mapnik/svg/svg_path_commands.hpp | 7 +++---- include/mapnik/svg/svg_transform_grammar.hpp | 8 ++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/include/mapnik/svg/svg_path_commands.hpp b/include/mapnik/svg/svg_path_commands.hpp index 63680bd35..b5e01b5da 100644 --- a/include/mapnik/svg/svg_path_commands.hpp +++ b/include/mapnik/svg/svg_path_commands.hpp @@ -23,15 +23,14 @@ #ifndef SVG_COMMANDS_HPP #define SVG_COMMANDS_HPP +// mapnik +#include +// #include #include #include #include -#ifdef _WINDOWS -#define _USE_MATH_DEFINES -#include -#endif namespace mapnik { namespace svg { diff --git a/include/mapnik/svg/svg_transform_grammar.hpp b/include/mapnik/svg/svg_transform_grammar.hpp index a928b8a92..8f8c7f03f 100644 --- a/include/mapnik/svg/svg_transform_grammar.hpp +++ b/include/mapnik/svg/svg_transform_grammar.hpp @@ -25,7 +25,8 @@ #ifndef SVG_TRANSFORM_GRAMMAR_HPP #define SVG_TRANSFORM_GRAMMAR_HPP - +// mapnik +#include // agg #include // spirit @@ -35,11 +36,6 @@ #include #include -#ifdef _WINDOWS -#define _USE_MATH_DEFINES -#include -#endif - namespace mapnik { namespace svg { using namespace boost::spirit; From 298b7fa25391ec00326463e676cd224639f0c5fd Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 17:34:09 +0100 Subject: [PATCH 23/33] use make_shared --- include/mapnik/text_symbolizer.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mapnik/text_symbolizer.hpp b/include/mapnik/text_symbolizer.hpp index e322f4516..98c0e5181 100644 --- a/include/mapnik/text_symbolizer.hpp +++ b/include/mapnik/text_symbolizer.hpp @@ -47,10 +47,10 @@ struct MAPNIK_DECL text_symbolizer : public symbolizer_base { text_symbolizer(expression_ptr name, std::string const& face_name, unsigned size, color const& fill, - text_placements_ptr placements = text_placements_ptr(new text_placements_dummy) + text_placements_ptr placements = boost::make_shared() ); text_symbolizer(expression_ptr name, unsigned size, color const& fill, - text_placements_ptr placements = text_placements_ptr(new text_placements_dummy) + text_placements_ptr placements = boost::make_shared() ); text_symbolizer(text_symbolizer const& rhs); text_symbolizer& operator=(text_symbolizer const& rhs); From 64bc1ed36e62cb6e55dab01f835836928ef60d76 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Wed, 19 Oct 2011 17:34:44 +0100 Subject: [PATCH 24/33] ignore -Wparenthes , -Wchar-subscripts warnings (helpful with clang++) --- SConstruct | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index d84fb1bd4..5e463723c 100644 --- a/SConstruct +++ b/SConstruct @@ -1432,7 +1432,7 @@ if not preconfigured: if env['DEBUG']: env.Append(CXXFLAGS = gcc_cxx_flags + '-O0 -fno-inline %s' % debug_flags) else: - env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline %s' % (env['OPTIMIZATION'],ndebug_flags)) + env.Append(CXXFLAGS = gcc_cxx_flags + '-O%s -finline-functions -Wno-inline -Wno-parentheses -Wno-char-subscripts %s' % (env['OPTIMIZATION'],ndebug_flags)) if 'python' in env['BINDINGS']: if not os.access(env['PYTHON'], os.X_OK): From 7f57119dbd7139225f328bd009e21f55886cfaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mor=C3=A1vek=20=5BXificurk=5D?= Date: Wed, 19 Oct 2011 23:45:24 +0200 Subject: [PATCH 25/33] code cleanup --- include/mapnik/ctrans.hpp | 197 +++++++++++++++++++------------------- 1 file changed, 98 insertions(+), 99 deletions(-) diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index e18e80fd8..04b33f178 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -1,5 +1,5 @@ /***************************************************************************** - * + * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2006 Artem Pavlenko @@ -19,8 +19,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ - -//$Id: ctrans.hpp 39 2005-04-10 20:39:53Z pavlenko $ +//$Id$ #ifndef CTRANS_HPP #define CTRANS_HPP @@ -32,78 +31,72 @@ #include #include -namespace mapnik { +namespace mapnik +{ + typedef coord_array CoordinateArray; - -template + + +template struct MAPNIK_DECL coord_transform { coord_transform(Transform const& t, Geometry& geom) : t_(t), geom_(geom) {} - - unsigned vertex(double *x , double *y) const + + unsigned vertex(double *x, double *y) const { - unsigned command = geom_.vertex(x,y); - t_.forward(x,y); + unsigned command = geom_.vertex(x, y); + t_.forward(x, y); return command; } - - void rewind (unsigned pos) + + void rewind(unsigned pos) { geom_.rewind(pos); } - + private: Transform const& t_; Geometry& geom_; }; -template + +template struct MAPNIK_DECL coord_transform2 { typedef std::size_t size_type; typedef typename Geometry::value_type value_type; - coord_transform2(Transform const& t, - Geometry const& geom, + coord_transform2(Transform const& t, + Geometry const& geom, proj_transform const& prj_trans) - : t_(t), - geom_(geom), + : t_(t), + geom_(geom), prj_trans_(prj_trans) {} - - unsigned vertex(double * x , double * y) const + + unsigned vertex(double *x, double *y) const { - unsigned command(SEG_MOVETO); + unsigned command = SEG_MOVETO; bool ok = false; bool skipped_points = false; - while (!ok) + double z = 0; + while (!ok && command != SEG_END) { - command = geom_.vertex(x,y); - double z=0; - ok = prj_trans_.backward(*x,*y,z); + command = geom_.vertex(x, y); + ok = prj_trans_.backward(*x, *y, z); if (!ok) { skipped_points = true; } - ok = ok || (command == SEG_END); } if (skipped_points && (command == SEG_LINETO)) { command = SEG_MOVETO; } - t_.forward(x,y); + t_.forward(x, y); return command; } - /*unsigned vertex(double * x , double * y) const - { - unsigned command = geom_.vertex(x,y); - double z=0; - prj_trans_.backward(*x,*y,z); - t_.forward(x,y); - return command; - }*/ - - void rewind (unsigned pos) + void rewind(unsigned pos) { geom_.rewind(pos); } @@ -112,42 +105,42 @@ struct MAPNIK_DECL coord_transform2 { return geom_; } - + private: Transform const& t_; Geometry const& geom_; proj_transform const& prj_trans_; }; - -template + +template struct MAPNIK_DECL coord_transform3 { - coord_transform3(Transform const& t, - Geometry const& geom, + coord_transform3(Transform const& t, + Geometry const& geom, proj_transform const& prj_trans, int dx, int dy) - : t_(t), - geom_(geom), + : t_(t), + geom_(geom), prj_trans_(prj_trans), dx_(dx), dy_(dy) {} - - unsigned vertex(double * x , double * y) const + + unsigned vertex(double *x, double *y) const { - unsigned command = geom_.vertex(x,y); - double z=0; - prj_trans_.backward(*x,*y,z); - t_.forward(x,y); - *x+=dx_; - *y+=dy_; + unsigned command = geom_.vertex(x, y); + double z = 0; + prj_trans_.backward(*x, *y, z); + t_.forward(x, y); + *x += dx_; + *y += dy_; return command; } - - void rewind (unsigned pos) + + void rewind(unsigned pos) { geom_.rewind(pos); } - + private: Transform const& t_; Geometry const& geom_; @@ -155,7 +148,8 @@ private: int dx_; int dy_; }; - + + class CoordTransform { private: @@ -166,71 +160,74 @@ private: box2d extent_; double offset_x_; double offset_y_; + public: - CoordTransform(int width,int height,const box2d& extent, + CoordTransform(int width, int height, const box2d& extent, double offset_x = 0, double offset_y = 0) - :width_(width),height_(height),extent_(extent),offset_x_(offset_x),offset_y_(offset_y) + : width_(width), height_(height), extent_(extent), + offset_x_(offset_x), offset_y_(offset_y) { - sx_ = (double(width_))/extent_.width(); - sy_ = (double(height_))/extent_.height(); + sx_ = double(width_) / extent_.width(); + sy_ = double(height_) / extent_.height(); } - + inline int width() const { return width_; } - + inline int height() const { return height_; } - + inline double scale_x() const { return sx_; } - + inline double scale_y() const { return sy_; } - - inline void forward(double * x, double * y) const + + inline void forward(double *x, double *y) const { *x = (*x - extent_.minx()) * sx_ - offset_x_; *y = (extent_.maxy() - *y) * sy_ - offset_y_; } - - inline void backward(double * x, double * y) const + + inline void backward(double *x, double *y) const { - *x = extent_.minx() + (*x + offset_x_)/sx_; - *y = extent_.maxy() - (*y + offset_y_)/sy_; + *x = extent_.minx() + (*x + offset_x_) / sx_; + *y = extent_.maxy() - (*y + offset_y_) / sy_; } - + inline coord2d& forward(coord2d& c) const { - forward(&c.x,&c.y); - return c; - } - - inline coord2d& backward(coord2d& c) const - { - backward(&c.x,&c.y); + forward(&c.x, &c.y); return c; } - inline box2d forward(const box2d& e,proj_transform const& prj_trans) const + inline coord2d& backward(coord2d& c) const + { + backward(&c.x, &c.y); + return c; + } + + inline box2d forward(const box2d& e, + proj_transform const& prj_trans) const { double x0 = e.minx(); double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); double z = 0.0; - prj_trans.backward(x0,y0,z); - forward(&x0,&y0); - prj_trans.backward(x1,y1,z); - forward(&x1,&y1); - return box2d(x0,y0,x1,y1); + prj_trans.backward(x0, y0, z); + forward(&x0, &y0); + prj_trans.backward(x1, y1, z); + forward(&x1, &y1); + return box2d(x0, y0, x1, y1); } inline box2d forward(const box2d& e) const @@ -239,23 +236,24 @@ public: double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); - forward(&x0,&y0); - forward(&x1,&y1); - return box2d(x0,y0,x1,y1); + forward(&x0, &y0); + forward(&x1, &y1); + return box2d(x0, y0, x1, y1); } - inline box2d backward(const box2d& e,proj_transform const& prj_trans) const + inline box2d backward(const box2d& e, + proj_transform const& prj_trans) const { double x0 = e.minx(); double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); double z = 0.0; - backward(&x0,&y0); - prj_trans.forward(x0,y0,z); - backward(&x1,&y1); - prj_trans.forward(x1,y1,z); - return box2d(x0,y0,x1,y1); + backward(&x0, &y0); + prj_trans.forward(x0, y0, z); + backward(&x1, &y1); + prj_trans.forward(x1, y1, z); + return box2d(x0, y0, x1, y1); } inline box2d backward(const box2d& e) const @@ -264,28 +262,29 @@ public: double y0 = e.miny(); double x1 = e.maxx(); double y1 = e.maxy(); - backward(&x0,&y0); - backward(&x1,&y1); - return box2d(x0,y0,x1,y1); + backward(&x0, &y0); + backward(&x1, &y1); + return box2d(x0, y0, x1, y1); } inline CoordinateArray& forward(CoordinateArray& coords) const { - for (unsigned i=0;i const& extent() const { return extent_; From 6d1cd0aad90cc942d1112097cca4aa844bad8cac Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 19 Oct 2011 21:39:48 -0700 Subject: [PATCH 26/33] as a followup to fa7efc93909, remove unneeded operator-= from box2d --- bindings/python/mapnik_envelope.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/bindings/python/mapnik_envelope.cpp b/bindings/python/mapnik_envelope.cpp index edef9cccb..79c0fe1e5 100644 --- a/bindings/python/mapnik_envelope.cpp +++ b/bindings/python/mapnik_envelope.cpp @@ -264,7 +264,6 @@ void export_envelope() .def(self == self) // __eq__ .def(self != self) // __neq__ .def(self + self) // __add__ - //.def(self - self) // __sub__ .def(self * float()) // __mult__ .def(float() * self) .def(self / float()) // __div__ From c5a90023ae8150b789ce82650f1b8f18e1ce82f4 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Wed, 19 Oct 2011 21:40:49 -0700 Subject: [PATCH 27/33] reduce verbosity of configure output --- SConstruct | 46 ++++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/SConstruct b/SConstruct index 5e463723c..0d71d5457 100644 --- a/SConstruct +++ b/SConstruct @@ -525,19 +525,13 @@ if sys.platform == "win32": color_print(4,'\nWelcome to Mapnik...\n') -color_print(1,'*'*45) -color_print(1,'You are compiling Mapnik trunk (aka Mapnik2)') -color_print(1,'See important details at:\nhttp://trac.mapnik.org/wiki/Mapnik2') -color_print(1,('*'*45)+'\n') - - #### Custom Configure Checks ### def prioritize_paths(context,silent=True): env = context.env prefs = env['LINK_PRIORITY'].split(',') if not silent: - context.Message( 'Sorting lib and inc compiler paths by priority... %s' % ','.join(prefs) ) + context.Message( 'Sorting lib and inc compiler paths...') env['LIBPATH'] = sort_paths(env['LIBPATH'],prefs) env['CPPPATH'] = sort_paths(env['CPPPATH'],prefs) if silent: @@ -838,10 +832,10 @@ int main() major, minor = map(int,result.split('.')) if major >= 4 and minor >= 0: - color_print(4,'\nFound icu version... %s\n' % result) + color_print(4,'found: icu %s' % result) return True - color_print(1,'\nFound insufficient icu version... %s\n' % result) + color_print(1,'\nFound insufficient icu version... %s' % result) return False def boost_regex_has_icu(context): @@ -936,7 +930,7 @@ if not preconfigured: opts.files.append(conf) color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf) optfile = file(conf) - print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=") + #print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=") optfile.close() elif not conf == SCONS_LOCAL_CONFIG: @@ -1304,21 +1298,29 @@ if not preconfigured: env['HAS_CAIRO'] = False env['SKIPPED_DEPS'].append('cairomm-version') else: + print 'Checking for cairo/cairomm lib and include paths... ', cmd = 'pkg-config --libs --cflags cairomm-1.0' if env['RUNTIME_LINK'] == 'static': cmd += ' --static' cairo_env = env.Clone() - cairo_env.ParseConfig(cmd) - for lib in cairo_env['LIBS']: - if not lib in env['LIBS']: - env["CAIROMM_LINKFLAGS"].append(lib) - for lpath in cairo_env['LIBPATH']: - if not lpath in env['LIBPATH']: - env["CAIROMM_LIBPATHS"].append(lpath) - for inc in cairo_env['CPPPATH']: - if not inc in env['CPPPATH']: - env["CAIROMM_CPPPATHS"].append(inc) - env['HAS_CAIRO'] = True + try: + cairo_env.ParseConfig(cmd) + for lib in cairo_env['LIBS']: + if not lib in env['LIBS']: + env["CAIROMM_LINKFLAGS"].append(lib) + for lpath in cairo_env['LIBPATH']: + if not lpath in env['LIBPATH']: + env["CAIROMM_LIBPATHS"].append(lpath) + for inc in cairo_env['CPPPATH']: + if not inc in env['CPPPATH']: + env["CAIROMM_CPPPATHS"].append(inc) + env['HAS_CAIRO'] = True + print 'yes' + except OSError,e: + color_print(1,'no') + env['SKIPPED_DEPS'].append('cairo') + env['SKIPPED_DEPS'].append('cairomm') + color_print(1,'pkg-config reported: %s' % e) else: color_print(4,'Not building with cairo support, pass CAIRO=True to enable') @@ -1547,7 +1549,7 @@ if not preconfigured: except: pass if 'configure' in command_line_args: - color_print(4,'\n*Configure complete*\nNow run "python scons/scons.py" to build or "python scons/scons.py install" to install') + color_print(4,'\nConfigure completed: run `make` to build or `make install`') if not HELP_REQUESTED: Exit(0) From c87c05911b2fdac712a9d38095d57b1bf941c149 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 20 Oct 2011 14:38:04 +0100 Subject: [PATCH 28/33] revert back bool logic update urls -> https://github.com/mapnik/mapnik/issues/794 --- include/mapnik/value.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/mapnik/value.hpp b/include/mapnik/value.hpp index dfb62ff01..46fb7b05f 100644 --- a/include/mapnik/value.hpp +++ b/include/mapnik/value.hpp @@ -109,7 +109,8 @@ struct equals bool operator() (value_null, value_null) const { - return false; + // this changed from false to true - https://github.com/mapnik/mapnik/issues/794 + return true; } }; @@ -146,18 +147,21 @@ struct not_equals bool operator() (value_null, value_null) const { + // TODO - needs review - https://github.com/mapnik/mapnik/issues/794 return false; } template bool operator() (value_null, const T &) const { + // TODO - needs review - https://github.com/mapnik/mapnik/issues/794 return false; } template bool operator() (const T &, value_null) const { + // TODO - needs review - https://github.com/mapnik/mapnik/issues/794 return false; } }; From 39e1588f12e4368820245824ac8f90bf522e3a30 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 21 Oct 2011 01:55:07 -0700 Subject: [PATCH 29/33] sqlite: restore original sqlite dequoting function as the previous simplification did not work --- plugins/input/sqlite/sqlite_types.hpp | 32 ++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/plugins/input/sqlite/sqlite_types.hpp b/plugins/input/sqlite/sqlite_types.hpp index 49ae59f1e..df9bb16e0 100644 --- a/plugins/input/sqlite/sqlite_types.hpp +++ b/plugins/input/sqlite/sqlite_types.hpp @@ -45,13 +45,39 @@ class sqlite_utils { public: - static void dequote(std::string& s) + static void dequote(std::string & z) { - if (s[0] == '[' || s[0] == '\'' || s[0] == '"' || s[0] == '`') + char quote = z[0]; + + if (quote=='[' || quote=='\'' || quote=='"' || quote=='`') { - s = s.substr(1, s.length() - 1); + int iIn = 1; // Index of next byte to read from input + int iOut = 0; // Index of next byte to write to output + + // If the first byte was a '[', then the close-quote character is a ']' + if (quote == '[') + { + quote = ']'; + } + + while (z[iIn]) + { + if (z[iIn] == quote) + { + if (z[iIn+1] != quote) break; + z[iOut++] = quote; + iIn += 2; + } + else + { + z[iOut++] = z[iIn++]; + } + } + + z[iOut] = '\0'; } } + }; From 5e25e7cd6c07925dc7f33af49634f69cb62d5424 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 21 Oct 2011 03:41:20 -0700 Subject: [PATCH 30/33] sqlite: use boost::trim for dequoting of std::string --- plugins/input/sqlite/sqlite_types.hpp | 31 ++------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/plugins/input/sqlite/sqlite_types.hpp b/plugins/input/sqlite/sqlite_types.hpp index df9bb16e0..ba06b0c18 100644 --- a/plugins/input/sqlite/sqlite_types.hpp +++ b/plugins/input/sqlite/sqlite_types.hpp @@ -32,6 +32,7 @@ // boost #include +#include // sqlite extern "C" { @@ -47,35 +48,7 @@ public: static void dequote(std::string & z) { - char quote = z[0]; - - if (quote=='[' || quote=='\'' || quote=='"' || quote=='`') - { - int iIn = 1; // Index of next byte to read from input - int iOut = 0; // Index of next byte to write to output - - // If the first byte was a '[', then the close-quote character is a ']' - if (quote == '[') - { - quote = ']'; - } - - while (z[iIn]) - { - if (z[iIn] == quote) - { - if (z[iIn+1] != quote) break; - z[iOut++] = quote; - iIn += 2; - } - else - { - z[iOut++] = z[iIn++]; - } - } - - z[iOut] = '\0'; - } + boost::algorithm::trim_if(z,boost::algorithm::is_any_of("[]'\"`")); } }; From b8ed785d7d195e2c13c68a8b3c90086cf7bf9a68 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Fri, 21 Oct 2011 20:02:34 +0100 Subject: [PATCH 31/33] use static_cast --- include/mapnik/ctrans.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mapnik/ctrans.hpp b/include/mapnik/ctrans.hpp index 04b33f178..1bfac5b8c 100644 --- a/include/mapnik/ctrans.hpp +++ b/include/mapnik/ctrans.hpp @@ -167,8 +167,8 @@ public: : width_(width), height_(height), extent_(extent), offset_x_(offset_x), offset_y_(offset_y) { - sx_ = double(width_) / extent_.width(); - sy_ = double(height_) / extent_.height(); + sx_ = static_cast(width_) / extent_.width(); + sy_ = static_cast(height_) / extent_.height(); } inline int width() const From c57773de6b8e2a5104f1fc7b12df0ec3782d2820 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 21 Oct 2011 14:44:18 -0700 Subject: [PATCH 32/33] tests for sqlite dequoting --- tests/python_tests/sqlite_test.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/python_tests/sqlite_test.py b/tests/python_tests/sqlite_test.py index 352213f1e..4d2b0514a 100644 --- a/tests/python_tests/sqlite_test.py +++ b/tests/python_tests/sqlite_test.py @@ -58,6 +58,37 @@ def test_attachdb_with_explicit_index(): 'insert into scratch.myindex values (1,-7799225.5,-7778571.0,1393264.125,1417719.375)\n' ) +def test_dequoting_of_subqueries(): + # The point table and index is in the qgis_spatiallite.sqlite + # database. If either is not found, then this fails + ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite', + table='world_merc', + ) + fs = ds.featureset() + feature = fs.next() + eq_(feature['OGC_FID'],1) + eq_(feature['fips'],u'AC') + + # TODO: + # select * from world_merc fails + # as rowid is dropped + ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite', + table='(select *,rowid from world_merc)', + ) + fs = ds.featureset() + feature = fs.next() + print feature + eq_(feature['OGC_FID'],1) + eq_(feature['fips'],u'AC') + + ds = mapnik2.SQLite(file='../data/sqlite/world.sqlite', + table='(select GEOMETRY,OGC_FID as rowid,fips from world_merc)', + ) + fs = ds.featureset() + feature = fs.next() + print feature + eq_(feature['rowid'],1) + eq_(feature['fips'],u'AC') if __name__ == "__main__": setup() From d1c8818029e83bdc3d91d7bffd09b7ce71d716f1 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Fri, 21 Oct 2011 15:55:58 -0700 Subject: [PATCH 33/33] remove area as it is unused (not needed by anything yet) - closes #846 --- bindings/python/mapnik_geometry.cpp | 1 - include/mapnik/geometry.hpp | 22 +--------------------- tests/python_tests/feature_test.py | 4 ---- 3 files changed, 1 insertion(+), 26 deletions(-) diff --git a/bindings/python/mapnik_geometry.cpp b/bindings/python/mapnik_geometry.cpp index c1a1c871e..611c1c580 100644 --- a/bindings/python/mapnik_geometry.cpp +++ b/bindings/python/mapnik_geometry.cpp @@ -78,7 +78,6 @@ void export_geometry() .def("envelope",&geometry_type::envelope) // .def("__str__",&geometry_type::to_string) .def("type",&geometry_type::type) - .def("area",&geometry_type::area) // TODO add other geometry_type methods ; diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index dea3125cd..33153b9e9 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -68,27 +68,7 @@ public: { return type_; } - - double area() const - { - double sum = 0.0; - double x(0); - double y(0); - rewind(0); - double xs = x; - double ys = y; - for (unsigned i=0;i envelope() const { box2d result; diff --git a/tests/python_tests/feature_test.py b/tests/python_tests/feature_test.py index b933a4383..828995d3c 100644 --- a/tests/python_tests/feature_test.py +++ b/tests/python_tests/feature_test.py @@ -18,10 +18,6 @@ class FeatureTest(unittest.TestCase): f = self.makeOne(1, 'POLYGON ((35 10, 10 20, 15 40, 45 45, 35 10),(20 30, 35 35, 30 20, 20 30))', foo="bar") self.failUnlessEqual(f['foo'], 'bar') self.failUnlessEqual(f.envelope(),Box2d(10.0,10.0,45.0,45.0)) - area = 0.0 - for g in f.geometries(): - area += g.area() - self.failUnlessEqual(area,-450.0) def test_set_get_properties(self): f = self.makeOne(1)