attempt to handle multi-polygons in shape.input

This commit is contained in:
artemp 2014-02-24 15:20:06 +00:00
parent 7adb29bdd0
commit ecc5acbdb9
2 changed files with 51 additions and 4 deletions

View file

@ -247,6 +247,47 @@ double path_length(PathType & path)
return length;
}
template <typename PathType>
bool hit_test_first(PathType & path, double x, double y, double tol)
{
bool inside=false;
double x0 = 0;
double y0 = 0;
double x1 = 0;
double y1 = 0;
path.rewind(0);
unsigned command = path.vertex(&x0, &y0);
if (command == SEG_END)
{
return false;
}
unsigned count = 0;
mapnik::geometry_type::types geom_type = static_cast<mapnik::geometry_type::types>(path.type());
while (SEG_END != (command = path.vertex(&x1, &y1)))
{
if (command == SEG_CLOSE)
{
break;
}
++count;
if (command == SEG_MOVETO)
{
x0 = x1;
y0 = y1;
continue;
}
if ((((y1 <= y) && (y < y0)) ||
((y0 <= y) && (y < y1))) &&
(x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1))
inside=!inside;
x0 = x1;
y0 = y1;
}
return inside;
}
namespace label {
template <typename PathType>

View file

@ -25,12 +25,13 @@
// mapnik
#include <mapnik/debug.hpp>
#include <mapnik/datasource.hpp>
#include <mapnik/geom_util.hpp>
// boost
using mapnik::datasource_exception;
using mapnik::geometry_type;
using mapnik::hit_test_first;
const std::string shape_io::SHP = ".shp";
const std::string shape_io::DBF = ".dbf";
const std::string shape_io::INDEX = ".index";
@ -156,9 +157,9 @@ void shape_io::read_polygon(shape_file::record_type & record, mapnik::geometry_c
parts[i] = record.read_ndr_integer();
}
std::unique_ptr<geometry_type> poly(new geometry_type(mapnik::geometry_type::types::Polygon));
for (int k = 0; k < num_parts; ++k)
{
std::unique_ptr<geometry_type> poly(new geometry_type(mapnik::geometry_type::types::Polygon));
int start = parts[k];
int end;
if (k == num_parts - 1)
@ -172,14 +173,19 @@ void shape_io::read_polygon(shape_file::record_type & record, mapnik::geometry_c
double x = record.read_double();
double y = record.read_double();
if (k > 0 && !hit_test_first(*poly, x, y, 0))
{
geom.push_back(poly.release());
poly.reset(new geometry_type(mapnik::geometry_type::types::Polygon));
}
poly->move_to(x, y);
for (int j=start+1;j<end;j++)
for (int j = start + 1; j < end; ++j)
{
x = record.read_double();
y = record.read_double();
poly->line_to(x, y);
}
poly->close_path();
geom.push_back(poly.release());
}
geom.push_back(poly.release());
}