properly skip empty geometries - refs #1333 and #1305 an #1132

+ remove redundant ar.size() > 0 check
+ use std::auto_ptr<geometry_type> to avoid memory leaks and
  improve exception safety.
This commit is contained in:
Dane Springmeyer 2012-07-20 15:28:10 -07:00 committed by artemp
parent 0e7414ea1d
commit 9c5dbc20c5

View file

@ -113,9 +113,6 @@ public:
{
int type = read_integer();
#ifdef MAPNIK_LOG
MAPNIK_LOG_DEBUG(wkb_reader) << "wkb_reader: Read=" << wkb_geometry_type_string(type) << "," << type;
#endif
switch (type)
{
case wkbPoint:
@ -246,9 +243,9 @@ private:
void read_point(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(Point);
double x = read_double();
double y = read_double();
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
pt->move_to(x, y);
paths.push_back(pt);
}
@ -265,9 +262,9 @@ private:
void read_point_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* pt = new geometry_type(Point);
double x = read_double();
double y = read_double();
std::auto_ptr<geometry_type> pt(new geometry_type(Point));
pos_ += 8; // double z = read_double();
pt->move_to(x, y);
paths.push_back(pt);
@ -285,16 +282,19 @@ private:
void read_linestring(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* line = new geometry_type(LineString);
int num_points = read_integer();
CoordinateArray ar(num_points);
read_coords(ar);
line->move_to(ar[0].x, ar[0].y);
for (int i = 1; i < num_points; ++i)
if (num_points > 0)
{
line->line_to(ar[i].x, ar[i].y);
CoordinateArray ar(num_points);
read_coords(ar);
std::auto_ptr<geometry_type> line(new geometry_type(LineString));
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);
}
paths.push_back(line);
}
void read_multilinestring(boost::ptr_vector<geometry_type> & paths)
@ -309,16 +309,19 @@ private:
void read_linestring_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* line = new geometry_type(LineString);
int num_points = read_integer();
CoordinateArray ar(num_points);
read_coords_xyz(ar);
line->move_to(ar[0].x, ar[0].y);
for (int i = 1; i < num_points; ++i)
if (num_points > 0)
{
line->line_to(ar[i].x, ar[i].y);
CoordinateArray ar(num_points);
read_coords_xyz(ar);
std::auto_ptr<geometry_type> line(new geometry_type(LineString));
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);
}
paths.push_back(line);
}
void read_multilinestring_xyz(boost::ptr_vector<geometry_type> & paths)
@ -334,22 +337,27 @@ private:
void read_polygon(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* poly = new geometry_type(Polygon);
int num_rings = read_integer();
unsigned capacity = 0;
for (int i = 0; i < num_rings; ++i)
if (num_rings > 0)
{
int num_points = read_integer();
capacity += num_points;
CoordinateArray ar(num_points);
read_coords(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
for (int i = 0; i < num_rings; ++i)
{
poly->line_to(ar[j].x, ar[j].y);
int num_points = read_integer();
if (num_points > 0)
{
CoordinateArray ar(num_points);
read_coords(ar);
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);
}
}
}
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
paths.push_back(poly);
}
paths.push_back(poly);
}
void read_multipolygon(boost::ptr_vector<geometry_type> & paths)
@ -364,22 +372,27 @@ private:
void read_polygon_xyz(boost::ptr_vector<geometry_type> & paths)
{
geometry_type* poly = new geometry_type(Polygon);
int num_rings = read_integer();
unsigned capacity = 0;
for (int i = 0; i < num_rings; ++i)
if (num_rings > 0)
{
int num_points = read_integer();
capacity += num_points;
CoordinateArray ar(num_points);
read_coords_xyz(ar);
poly->move_to(ar[0].x, ar[0].y);
for (int j = 1; j < num_points; ++j)
std::auto_ptr<geometry_type> poly(new geometry_type(Polygon));
for (int i = 0; i < num_rings; ++i)
{
poly->line_to(ar[j].x, ar[j].y);
int num_points = read_integer();
if (num_points > 0)
{
CoordinateArray ar(num_points);
read_coords_xyz(ar);
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);
}
}
}
if (poly->size() > 2) // ignore if polygon has less than 3 vertices
paths.push_back(poly);
}
paths.push_back(poly);
}
void read_multipolygon_xyz(boost::ptr_vector<geometry_type> & paths)
@ -402,33 +415,32 @@ private:
}
}
#ifdef MAPNIK_LOG
std::string wkb_geometry_type_string(int type)
{
std::stringstream s;
switch (type)
{
case wkbPoint: s << "wkbPoint"; break;
case wkbLineString: s << "wkbLineString"; break;
case wkbPolygon: s << "wkbPolygon"; break;
case wkbMultiPoint: s << "wkbMultiPoint"; break;
case wkbMultiLineString: s << "wkbMultiLineString"; break;
case wkbMultiPolygon: s << "wkbMultiPolygon"; break;
case wkbGeometryCollection: s << "wkbGeometryCollection"; break;
case wkbPointZ: s << "wkbPointZ"; break;
case wkbLineStringZ: s << "wkbLineStringZ"; break;
case wkbPolygonZ: s << "wkbPolygonZ"; break;
case wkbMultiPointZ: s << "wkbMultiPointZ"; break;
case wkbMultiLineStringZ: s << "wkbMultiLineStringZ"; break;
case wkbMultiPolygonZ: s << "wkbMultiPolygonZ"; break;
case wkbGeometryCollectionZ: s << "wkbGeometryCollectionZ"; break;
default: s << "wkbUknown"; break;
case wkbPoint: s << "Point"; break;
case wkbLineString: s << "LineString"; break;
case wkbPolygon: s << "Polygon"; break;
case wkbMultiPoint: s << "MultiPoint"; break;
case wkbMultiLineString: s << "MultiLineString"; break;
case wkbMultiPolygon: s << "MultiPolygon"; break;
case wkbGeometryCollection: s << "GeometryCollection"; break;
case wkbPointZ: s << "PointZ"; break;
case wkbLineStringZ: s << "LineStringZ"; break;
case wkbPolygonZ: s << "PolygonZ"; break;
case wkbMultiPointZ: s << "MultiPointZ"; break;
case wkbMultiLineStringZ: s << "MultiLineStringZ"; break;
case wkbMultiPolygonZ: s << "MultiPolygonZ"; break;
case wkbGeometryCollectionZ: s << "GeometryCollectionZ"; break;
default: s << "wkbUknown(" << type << ")"; break;
}
return s.str();
}
#endif
};
bool geometry_utils::from_wkb(boost::ptr_vector<geometry_type>& paths,