+ explicit polygon path closing
This commit is contained in:
parent
6d0caf88f5
commit
e9f03a565f
11 changed files with 45 additions and 87 deletions
|
@ -245,6 +245,7 @@ double path_length(PathType & path)
|
||||||
double length = 0;
|
double length = 0;
|
||||||
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||||
{
|
{
|
||||||
|
if (command == SEG_CLOSE) continue;
|
||||||
length += distance(x0,y0,x1,y1);
|
length += distance(x0,y0,x1,y1);
|
||||||
x0 = x1;
|
x0 = x1;
|
||||||
y0 = y1;
|
y0 = y1;
|
||||||
|
@ -268,6 +269,7 @@ bool middle_point(PathType & path, double & x, double & y)
|
||||||
double dist = 0.0;
|
double dist = 0.0;
|
||||||
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||||
{
|
{
|
||||||
|
if (command == SEG_CLOSE) continue;
|
||||||
double seg_length = distance(x0, y0, x1, y1);
|
double seg_length = distance(x0, y0, x1, y1);
|
||||||
|
|
||||||
if ( dist + seg_length >= mid_length)
|
if ( dist + seg_length >= mid_length)
|
||||||
|
@ -307,6 +309,7 @@ bool centroid(PathType & path, double & x, double & y)
|
||||||
unsigned count = 1;
|
unsigned count = 1;
|
||||||
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||||
{
|
{
|
||||||
|
if (command == SEG_CLOSE) continue;
|
||||||
double dx0 = x0 - start_x;
|
double dx0 = x0 - start_x;
|
||||||
double dy0 = y0 - start_y;
|
double dy0 = y0 - start_y;
|
||||||
double dx1 = x1 - start_x;
|
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)))
|
while (SEG_END != (command = path.vertex(&x1, &y1)))
|
||||||
{
|
{
|
||||||
|
if (command == SEG_CLOSE) continue;
|
||||||
double dx0 = x0 - start_x;
|
double dx0 = x0 - start_x;
|
||||||
double dy0 = y0 - start_y;
|
double dy0 = y0 - start_y;
|
||||||
double dx1 = x1 - start_x;
|
double dx1 = x1 - start_x;
|
||||||
|
|
|
@ -122,37 +122,9 @@ public:
|
||||||
push_vertex(x,y,SEG_MOVETO);
|
push_vertex(x,y,SEG_MOVETO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void close(coord_type x, coord_type y)
|
void close_path()
|
||||||
{
|
{
|
||||||
push_vertex(x,y,SEG_CLOSE);
|
push_vertex(0,0,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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned vertex(double* x, double* y) const
|
unsigned vertex(double* x, double* y) const
|
||||||
|
|
|
@ -67,7 +67,7 @@ struct close_path
|
||||||
void operator() (T path) const
|
void operator() (T path) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( path!=0 );
|
BOOST_ASSERT( path!=0 );
|
||||||
path->set_close();
|
path->close_path();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -181,17 +181,15 @@ wkb_buffer_ptr to_polygon_wkb( GeometryType const& g, wkbByteOrder byte_order)
|
||||||
if (command == SEG_MOVETO)
|
if (command == SEG_MOVETO)
|
||||||
{
|
{
|
||||||
rings.push_back(new linear_ring); // start new loop
|
rings.push_back(new linear_ring); // start new loop
|
||||||
start_x = x;
|
rings.back().push_back(std::make_pair(x,y));
|
||||||
start_y = y;
|
|
||||||
size += 4; // num_points
|
size += 4; // num_points
|
||||||
|
size += 2 * 8; // point
|
||||||
}
|
}
|
||||||
else if (command == SEG_CLOSE)
|
else if (command == SEG_LINETO)
|
||||||
{
|
{
|
||||||
x = start_x;
|
rings.back().push_back(std::make_pair(x,y));
|
||||||
y = start_y;
|
size += 2 * 8; // point
|
||||||
}
|
}
|
||||||
rings.back().push_back(std::make_pair(x,y));
|
|
||||||
size += 2 * 8; // point
|
|
||||||
}
|
}
|
||||||
unsigned num_rings = rings.size();
|
unsigned num_rings = rings.size();
|
||||||
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
|
wkb_buffer_ptr wkb = boost::make_shared<wkb_buffer>(size);
|
||||||
|
|
|
@ -71,7 +71,7 @@ namespace mapnik { namespace wkt {
|
||||||
void operator() (T path) const
|
void operator() (T path) const
|
||||||
{
|
{
|
||||||
BOOST_ASSERT( path!=0 );
|
BOOST_ASSERT( path!=0 );
|
||||||
path->set_close();
|
path->close_path();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -111,21 +111,21 @@ void ogr_converter::convert_polygon(OGRPolygon* geom, feature_ptr feature)
|
||||||
std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon));
|
std::auto_ptr<geometry_type> poly(new geometry_type(mapnik::Polygon));
|
||||||
|
|
||||||
poly->move_to(exterior->getX(0), exterior->getY(0));
|
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->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)
|
for (int r = 0; r < num_interior; ++r)
|
||||||
{
|
{
|
||||||
OGRLinearRing* interior = geom->getInteriorRing(r);
|
OGRLinearRing* interior = geom->getInteriorRing(r);
|
||||||
num_points = interior->getNumPoints();
|
num_points = interior->getNumPoints();
|
||||||
poly->move_to(interior->getX(0), interior->getY(0));
|
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->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);
|
feature->paths().push_back(poly);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,22 +177,13 @@ void shape_io::read_polygon(shape_file::record_type & record, mapnik::geometry_c
|
||||||
poly->move_to(x, y);
|
poly->move_to(x, y);
|
||||||
double start_x = x;
|
double start_x = x;
|
||||||
double start_y = y;
|
double start_y = y;
|
||||||
for (int j=start+1;j<end-1;j++)
|
for (int j=start+1;j<end;j++)
|
||||||
{
|
{
|
||||||
x = record.read_double();
|
x = record.read_double();
|
||||||
y = record.read_double();
|
y = record.read_double();
|
||||||
poly->line_to(x, y);
|
poly->line_to(x, y);
|
||||||
}
|
}
|
||||||
x = record.read_double();
|
poly->close_path();
|
||||||
y = record.read_double();
|
|
||||||
if (x == start_x && y == start_y)
|
|
||||||
{
|
|
||||||
poly->close(x, y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
poly->line_to(x, y);
|
|
||||||
}
|
|
||||||
geom.push_back(poly);
|
geom.push_back(poly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,10 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
|
||||||
frame->line_to(x,y);
|
frame->line_to(x,y);
|
||||||
face_segments.push_back(segment_t(x0,y0,x,y));
|
face_segments.push_back(segment_t(x0,y0,x,y));
|
||||||
}
|
}
|
||||||
|
else if (cm == SEG_CLOSE)
|
||||||
|
{
|
||||||
|
frame->close_path();
|
||||||
|
}
|
||||||
x0 = x;
|
x0 = x;
|
||||||
y0 = y;
|
y0 = y;
|
||||||
}
|
}
|
||||||
|
@ -145,6 +149,11 @@ void agg_renderer<T>::process(building_symbolizer const& sym,
|
||||||
frame->line_to(x,y+height);
|
frame->line_to(x,y+height);
|
||||||
roof->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);
|
path_type path(t_,*frame,prj_trans);
|
||||||
|
|
|
@ -378,11 +378,15 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
|
||||||
{
|
{
|
||||||
frame->move_to(x,y);
|
frame->move_to(x,y);
|
||||||
}
|
}
|
||||||
else if (cm == SEG_LINETO || cm == SEG_CLOSE)
|
else if (cm == SEG_LINETO)
|
||||||
{
|
{
|
||||||
frame->line_to(x,y);
|
frame->line_to(x,y);
|
||||||
face_segments.push_back(segment_t(x0,y0,x,y));
|
face_segments.push_back(segment_t(x0,y0,x,y));
|
||||||
}
|
}
|
||||||
|
else if (cm = SEG_CLOSE)
|
||||||
|
{
|
||||||
|
frame->close_path();
|
||||||
|
}
|
||||||
x0 = x;
|
x0 = x;
|
||||||
y0 = y;
|
y0 = y;
|
||||||
}
|
}
|
||||||
|
@ -417,11 +421,16 @@ void cairo_renderer_base::process(building_symbolizer const& sym,
|
||||||
frame->move_to(x,y+height);
|
frame->move_to(x,y+height);
|
||||||
roof->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);
|
frame->line_to(x,y+height);
|
||||||
roof->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);
|
path_type path(t_, *frame, prj_trans);
|
||||||
|
|
30
src/wkb.cpp
30
src/wkb.cpp
|
@ -353,25 +353,14 @@ private:
|
||||||
CoordinateArray ar(num_points);
|
CoordinateArray ar(num_points);
|
||||||
read_coords(ar);
|
read_coords(ar);
|
||||||
poly->move_to(ar[0].x, ar[0].y);
|
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);
|
poly->line_to(ar[j].x, ar[j].y);
|
||||||
}
|
}
|
||||||
|
poly->close_path();
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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);
|
paths.push_back(poly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,20 +389,11 @@ private:
|
||||||
CoordinateArray ar(num_points);
|
CoordinateArray ar(num_points);
|
||||||
read_coords_xyz(ar);
|
read_coords_xyz(ar);
|
||||||
poly->move_to(ar[0].x, ar[0].y);
|
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);
|
poly->line_to(ar[j].x, ar[j].y);
|
||||||
}
|
}
|
||||||
if (ar[0].x == ar[num_points-1].x &&
|
poly->close_path();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
|
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
|
||||||
|
|
|
@ -66,8 +66,6 @@ wkt_generator<OutputIterator, Geometry>::wkt_generator(bool single)
|
||||||
using boost::spirit::karma::_b;
|
using boost::spirit::karma::_b;
|
||||||
using boost::spirit::karma::_c;
|
using boost::spirit::karma::_c;
|
||||||
using boost::spirit::karma::_r1;
|
using boost::spirit::karma::_r1;
|
||||||
using boost::spirit::karma::_r2;
|
|
||||||
using boost::spirit::karma::_r3;
|
|
||||||
using boost::spirit::karma::eps;
|
using boost::spirit::karma::eps;
|
||||||
using boost::spirit::karma::string;
|
using boost::spirit::karma::string;
|
||||||
|
|
||||||
|
@ -98,15 +96,12 @@ wkt_generator<OutputIterator, Geometry>::wkt_generator(bool single)
|
||||||
;
|
;
|
||||||
|
|
||||||
polygon_coord %= ( &uint_(mapnik::SEG_MOVETO)
|
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 = "),("]
|
<< string[ if_ (_r1 > 1) [_1 = "),("]
|
||||||
.else_[_1 = "("]]
|
.else_[_1 = "("]]
|
||||||
|
|
|
|
||||||
&uint_(mapnik::SEG_LINETO)
|
&uint_(mapnik::SEG_LINETO)
|
||||||
<< lit(',') << eps[_a = _x(_val)][_b = _y(_val)]
|
<< lit(',') << eps[_a = _x(_val)][_b = _y(_val)]
|
||||||
|
|
|
||||||
&uint_(mapnik::SEG_CLOSE)
|
|
||||||
<< lit(',') << eps[_a = _r2][_b = _r3]
|
|
||||||
)
|
)
|
||||||
<< coordinate[_1 = _a]
|
<< coordinate[_1 = _a]
|
||||||
<< lit(' ')
|
<< lit(' ')
|
||||||
|
|
Loading…
Reference in a new issue