diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index 94d1b746f..f8a676b35 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -245,6 +245,7 @@ double path_length(PathType & path) double length = 0; while (SEG_END != (command = path.vertex(&x1, &y1))) { + if (command == SEG_CLOSE) continue; length += distance(x0,y0,x1,y1); x0 = x1; y0 = y1; @@ -268,6 +269,7 @@ bool middle_point(PathType & path, double & x, double & y) double dist = 0.0; while (SEG_END != (command = path.vertex(&x1, &y1))) { + if (command == SEG_CLOSE) continue; double seg_length = distance(x0, y0, x1, y1); if ( dist + seg_length >= mid_length) @@ -307,6 +309,7 @@ bool centroid(PathType & path, double & x, double & y) unsigned count = 1; while (SEG_END != (command = path.vertex(&x1, &y1))) { + if (command == SEG_CLOSE) continue; double dx0 = x0 - start_x; double dy0 = y0 - start_y; double dx1 = x1 - start_x; @@ -370,6 +373,7 @@ bool centroid_geoms(Iter start, Iter end, double & x, double & y) while (SEG_END != (command = path.vertex(&x1, &y1))) { + if (command == SEG_CLOSE) continue; double dx0 = x0 - start_x; double dy0 = y0 - start_y; double dx1 = x1 - start_x; diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp index 79acfef8d..c3f616f5f 100644 --- a/include/mapnik/geometry.hpp +++ b/include/mapnik/geometry.hpp @@ -122,37 +122,9 @@ public: push_vertex(x,y,SEG_MOVETO); } - void close(coord_type x, coord_type y) + void close_path() { - push_vertex(x,y,SEG_CLOSE); - } - - void set_close() - { - if (cont_.size() > 3) - { - unsigned cmd; - double x,y; - int index = cont_.size() - 1; - unsigned last_cmd = cont_.get_vertex(index,&x,&y); - if (last_cmd == SEG_LINETO) - { - double last_x = x; - double last_y = y; - for (int pos = index - 1; pos >=0 ; --pos) - { - cmd = cont_.get_vertex(pos,&x,&y); - if (cmd == SEG_MOVETO) - { - if (x == last_x && y == last_y) - { - cont_.set_command(index , SEG_CLOSE); - } - break; - } - } - } - } + push_vertex(0,0,SEG_CLOSE); } unsigned vertex(double* x, double* y) const diff --git a/include/mapnik/json/geometry_grammar.hpp b/include/mapnik/json/geometry_grammar.hpp index 058950433..a64ec6f05 100644 --- a/include/mapnik/json/geometry_grammar.hpp +++ b/include/mapnik/json/geometry_grammar.hpp @@ -67,7 +67,7 @@ struct close_path void operator() (T path) const { BOOST_ASSERT( path!=0 ); - path->set_close(); + path->close_path(); } }; diff --git a/include/mapnik/util/geometry_to_wkb.hpp b/include/mapnik/util/geometry_to_wkb.hpp index 4c3bb589f..942254483 100644 --- a/include/mapnik/util/geometry_to_wkb.hpp +++ b/include/mapnik/util/geometry_to_wkb.hpp @@ -181,17 +181,15 @@ wkb_buffer_ptr to_polygon_wkb( GeometryType const& g, wkbByteOrder byte_order) if (command == SEG_MOVETO) { rings.push_back(new linear_ring); // start new loop - start_x = x; - start_y = y; + rings.back().push_back(std::make_pair(x,y)); size += 4; // num_points + size += 2 * 8; // point } - else if (command == SEG_CLOSE) + else if (command == SEG_LINETO) { - x = start_x; - y = start_y; + rings.back().push_back(std::make_pair(x,y)); + size += 2 * 8; // point } - rings.back().push_back(std::make_pair(x,y)); - size += 2 * 8; // point } unsigned num_rings = rings.size(); wkb_buffer_ptr wkb = boost::make_shared(size); diff --git a/include/mapnik/wkt/wkt_grammar.hpp b/include/mapnik/wkt/wkt_grammar.hpp index 9ddb7d869..e7e986f59 100644 --- a/include/mapnik/wkt/wkt_grammar.hpp +++ b/include/mapnik/wkt/wkt_grammar.hpp @@ -71,7 +71,7 @@ namespace mapnik { namespace wkt { void operator() (T path) const { BOOST_ASSERT( path!=0 ); - path->set_close(); + path->close_path(); } }; diff --git a/plugins/input/ogr/ogr_converter.cpp b/plugins/input/ogr/ogr_converter.cpp index 7388ff9d4..8892ef1f9 100644 --- a/plugins/input/ogr/ogr_converter.cpp +++ b/plugins/input/ogr/ogr_converter.cpp @@ -111,21 +111,21 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature) std::auto_ptr poly(new geometry_type(mapnik::Polygon)); poly->move_to(exterior->getX(0), exterior->getY(0)); - for (int i = 1; i < num_points - 1; ++i) + for (int i = 1; i < num_points; ++i) { poly->line_to(exterior->getX(i), exterior->getY(i)); } - poly->close(exterior->getX(num_points-1), exterior->getY(num_points-1)); + poly->close_path(); for (int r = 0; r < num_interior; ++r) { OGRLinearRing* interior = geom->getInteriorRing(r); num_points = interior->getNumPoints(); poly->move_to(interior->getX(0), interior->getY(0)); - for (int i = 1; i < num_points - 1; ++i) + for (int i = 1; i < num_points; ++i) { poly->line_to(interior->getX(i), interior->getY(i)); } - poly->close(interior->getX(num_points-1), interior->getY(num_points-1)); + poly->close_path(); } feature->paths().push_back(poly); } diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 12d481fad..ca73dab9d 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -177,22 +177,13 @@ void shape_io::read_polygon(shape_file::record_type & record, mapnik::geometry_c poly->move_to(x, y); double start_x = x; double start_y = y; - for (int j=start+1;jline_to(x, y); } - x = record.read_double(); - y = record.read_double(); - if (x == start_x && y == start_y) - { - poly->close(x, y); - } - else - { - poly->line_to(x, y); - } + poly->close_path(); geom.push_back(poly); } } diff --git a/src/agg/process_building_symbolizer.cpp b/src/agg/process_building_symbolizer.cpp index 0211b6c3c..5addaac02 100644 --- a/src/agg/process_building_symbolizer.cpp +++ b/src/agg/process_building_symbolizer.cpp @@ -104,6 +104,10 @@ void agg_renderer::process(building_symbolizer const& sym, frame->line_to(x,y); face_segments.push_back(segment_t(x0,y0,x,y)); } + else if (cm == SEG_CLOSE) + { + frame->close_path(); + } x0 = x; y0 = y; } @@ -145,6 +149,11 @@ void agg_renderer::process(building_symbolizer const& sym, frame->line_to(x,y+height); roof->line_to(x,y+height); } + else if (cm == SEG_CLOSE) + { + frame->close_path(); + roof->close_path(); + } } path_type path(t_,*frame,prj_trans); diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index c6ca7a70c..dbab8a6d2 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -378,11 +378,15 @@ void cairo_renderer_base::process(building_symbolizer const& sym, { frame->move_to(x,y); } - else if (cm == SEG_LINETO || cm == SEG_CLOSE) + else if (cm == SEG_LINETO) { frame->line_to(x,y); face_segments.push_back(segment_t(x0,y0,x,y)); } + else if (cm = SEG_CLOSE) + { + frame->close_path(); + } x0 = x; y0 = y; } @@ -417,11 +421,16 @@ void cairo_renderer_base::process(building_symbolizer const& sym, frame->move_to(x,y+height); roof->move_to(x,y+height); } - else if (cm == SEG_LINETO || cm == SEG_CLOSE) + else if (cm == SEG_LINETO) { frame->line_to(x,y+height); roof->line_to(x,y+height); } + else if (cm == SEG_CLOSE) + { + frame->close_path(); + roof->close_path(); + } } path_type path(t_, *frame, prj_trans); diff --git a/src/wkb.cpp b/src/wkb.cpp index a43754387..ace66242a 100644 --- a/src/wkb.cpp +++ b/src/wkb.cpp @@ -353,25 +353,14 @@ private: CoordinateArray ar(num_points); read_coords(ar); poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points - 1; ++j) + for (int j = 1; j < num_points ; ++j) { poly->line_to(ar[j].x, ar[j].y); } - - if (ar[0].x == ar[num_points-1].x && - ar[0].y == ar[num_points-1].y) - { - poly->close(ar[num_points-1].x, ar[num_points-1].y); - } - else - { - // leave un-closed polygon intact - don't attempt to close them - poly->line_to(ar[num_points-1].x, ar[num_points-1].y); - } - poly->set_close(); + poly->close_path(); } } - if (poly->size() > 2) // ignore if polygon has less than 3 vertices + if (poly->size() > 3) // ignore if polygon has less than (3 + close_path) vertices paths.push_back(poly); } } @@ -400,20 +389,11 @@ private: CoordinateArray ar(num_points); read_coords_xyz(ar); poly->move_to(ar[0].x, ar[0].y); - for (int j = 1; j < num_points - 1; ++j) + for (int j = 1; j < num_points; ++j) { poly->line_to(ar[j].x, ar[j].y); } - if (ar[0].x == ar[num_points-1].x && - ar[0].y == ar[num_points-1].y) - { - poly->close(ar[num_points-1].x, ar[num_points-1].y); - } - else - { - // leave un-closed polygon intact- don't attempt to close them - poly->line_to(ar[num_points-1].x, ar[num_points-1].y); - } + poly->close_path(); } } if (poly->size() > 2) // ignore if polygon has less than 3 vertices diff --git a/src/wkt/wkt_generator.cpp b/src/wkt/wkt_generator.cpp index 67ca61295..16f81bfe5 100644 --- a/src/wkt/wkt_generator.cpp +++ b/src/wkt/wkt_generator.cpp @@ -66,8 +66,6 @@ wkt_generator::wkt_generator(bool single) using boost::spirit::karma::_b; using boost::spirit::karma::_c; using boost::spirit::karma::_r1; - using boost::spirit::karma::_r2; - using boost::spirit::karma::_r3; using boost::spirit::karma::eps; using boost::spirit::karma::string; @@ -98,15 +96,12 @@ wkt_generator::wkt_generator(bool single) ; polygon_coord %= ( &uint_(mapnik::SEG_MOVETO) - << eps[_r1 += 1][_a = _r2 = _x(_val)][ _b = _r3 = _y(_val)] + << eps[_r1 += 1][_a = _x(_val)][ _b = _y(_val)] << string[ if_ (_r1 > 1) [_1 = "),("] .else_[_1 = "("]] | &uint_(mapnik::SEG_LINETO) << lit(',') << eps[_a = _x(_val)][_b = _y(_val)] - | - &uint_(mapnik::SEG_CLOSE) - << lit(',') << eps[_a = _r2][_b = _r3] ) << coordinate[_1 = _a] << lit(' ')