From faaa4f6e3f3cd848a2edce60be71e4e0c1d652db Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Thu, 5 Jan 2012 16:24:38 +0000 Subject: [PATCH] shape: check if multiple parts are interior rings or separate polygons. Currently only test if first coordinate inside exterior ring and assume first ring is exterior. If this approach is not robust enough we can calculate ring orientations instead. Shape file convention is: CW - exterior, CCW - interior. very simple --- plugins/input/shape/shape_io.cpp | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/plugins/input/shape/shape_io.cpp b/plugins/input/shape/shape_io.cpp index 54b7f32fc..1fc570c24 100644 --- a/plugins/input/shape/shape_io.cpp +++ b/plugins/input/shape/shape_io.cpp @@ -110,12 +110,12 @@ void shape_io::read_polyline(mapnik::geometry_container & geom) { shape_file::record_type record(reclength_ * 2 - 36); shp_.read_record(record); - + int num_parts = record.read_ndr_integer(); int num_points = record.read_ndr_integer(); if (num_parts == 1) { - geometry_type* line = new geometry_type(mapnik::LineString); + geometry_type* line = new geometry_type(mapnik::LineString); record.skip(4); double x = record.read_double(); double y = record.read_double(); @@ -139,7 +139,7 @@ void shape_io::read_polyline(mapnik::geometry_container & geom) int start, end; for (int k = 0; k < num_parts; ++k) { - geometry_type* line = new geometry_type(mapnik::LineString); + geometry_type* line = new geometry_type(mapnik::LineString); start = parts[k]; if (k == num_parts - 1) { @@ -186,19 +186,21 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) { shape_file::record_type record(reclength_ * 2 - 36); shp_.read_record(record); - + int num_parts = record.read_ndr_integer(); int num_points = record.read_ndr_integer(); std::vector parts(num_parts); - + for (int i = 0; i < num_parts; ++i) { parts[i] = record.read_ndr_integer(); } + geometry_type* poly = new geometry_type(mapnik::Polygon); + for (int k = 0; k < num_parts; k++) { - geometry_type* poly = new geometry_type(mapnik::Polygon); + int start = parts[k]; int end; if (k == num_parts - 1) @@ -212,6 +214,13 @@ void shape_io::read_polygon(mapnik::geometry_container & geom) double x = record.read_double(); double y = record.read_double(); + + if (k > 0 && !poly->hit_test(x,y,0)) + { + geom.push_back(poly); + poly = new geometry_type(mapnik::Polygon); + } + poly->move_to(x, y); for (int j=start+1;jline_to(x, y); } - geom.push_back(poly); } + + geom.push_back(poly); // z-range //double z0=record.read_double(); //double z1=record.read_double();