diff --git a/bindings/python/mapnik_python.cpp b/bindings/python/mapnik_python.cpp index b041f16e2..ce6fdf149 100644 --- a/bindings/python/mapnik_python.cpp +++ b/bindings/python/mapnik_python.cpp @@ -194,7 +194,7 @@ void render_with_detector( unsigned offset_y = 0u) { python_unblock_auto_block b; - mapnik::agg_renderer ren(map,image,detector); + mapnik::agg_renderer ren(map,image,detector,scale_factor,offset_x,offset_y); ren.apply(); } diff --git a/include/mapnik/geom_util.hpp b/include/mapnik/geom_util.hpp index b2fe88084..7e0d65616 100644 --- a/include/mapnik/geom_util.hpp +++ b/include/mapnik/geom_util.hpp @@ -26,6 +26,7 @@ // mapnik #include #include +#include // for eGeomType (TODO: avoid this interdependence) // boost #include @@ -414,11 +415,18 @@ bool hit_test(PathType & path, double x, double y, double tol) double y1 = 0; path.rewind(0); unsigned command = path.vertex(&x0, &y0); - if (command == SEG_END) return false; + if (command == SEG_END) + { + return false; + } unsigned count = 0; + mapnik::eGeomType geom_type = static_cast(path.type()); while (SEG_END != (command = path.vertex(&x1, &y1))) { - if (command == SEG_CLOSE) continue; + if (command == SEG_CLOSE) + { + continue; + } ++count; if (command == SEG_MOVETO) { @@ -426,18 +434,34 @@ bool hit_test(PathType & path, double x, double y, double tol) y0 = y1; continue; } - if ((((y1 <= y) && (y < y0)) || - ((y0 <= y) && (y < y1))) && - (x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1)) - inside=!inside; - + switch(geom_type) + { + case mapnik::Polygon: + { + if ((((y1 <= y) && (y < y0)) || + ((y0 <= y) && (y < y1))) && + (x < (x0 - x1) * (y - y1)/ (y0 - y1) + x1)) + inside=!inside; + break; + } + case mapnik::LineString: + { + double distance = point_to_segment_distance(x,y,x0,y0,x1,y1); + if (distance < tol) + return true; + break; + } + default: + break; + } x0 = x1; y0 = y1; } + // TODO - handle multi-point? if (count == 0) // one vertex { - return distance(x, y, x0, y0) <= std::fabs(tol); + return distance(x, y, x0, y0) <= tol; } return inside; } diff --git a/tests/cpp_tests/label_algo_test.cpp b/tests/cpp_tests/label_algo_test.cpp index 268f63595..b5fed111a 100644 --- a/tests/cpp_tests/label_algo_test.cpp +++ b/tests/cpp_tests/label_algo_test.cpp @@ -34,7 +34,7 @@ int main(int argc, char** argv) // line with two verticies mapnik::geometry_type line(mapnik::geometry_type::types::LineString); line.move_to(0,0); - line.move_to(50,50); + line.line_to(50,50); BOOST_TEST( mapnik::label::centroid(line, x, y) ); BOOST_TEST( x == 25 ); BOOST_TEST( y == 25 ); @@ -42,6 +42,19 @@ int main(int argc, char** argv) // TODO - centroid and interior should be equal but they appear not to be (check largest) // MULTIPOLYGON(((-52 40,-60 32,-68 40,-60 48,-52 40)),((-60 50,-80 30,-100 49.9999999999999,-80.0000000000001 70,-60 50)),((-52 60,-60 52,-68 60,-60 68,-52 60))) + // hit tests + mapnik::geometry_type pt_hit(mapnik::Point); + pt_hit.move_to(10,10); + BOOST_TEST( mapnik::label::hit_test(pt_hit, 10, 10, 0.1) ); + BOOST_TEST( !mapnik::label::hit_test(pt_hit, 9, 9, 0) ); + BOOST_TEST( mapnik::label::hit_test(pt_hit, 9, 9, 1.5) ); + mapnik::geometry_type line_hit(mapnik::LineString); + line_hit.move_to(0,0); + line_hit.line_to(50,50); + BOOST_TEST( mapnik::label::hit_test(line_hit, 0, 0, 0.001) ); + BOOST_TEST( !mapnik::label::hit_test(line_hit, 1, 1, 0) ); + BOOST_TEST( mapnik::label::hit_test(line_hit, 1, 1, 1.001) ); + if (!::boost::detail::test_errors()) { if (quiet) std::clog << "\x1b[1;32m.\x1b[0m"; else std::clog << "C++ label algorithms: \x1b[1;32m✓ \x1b[0m\n";