test(mapnik::parameters const& params) : test_case(params), xml_(), extent_(), width_(*params.get<mapnik::value_integer>("width",256)), height_(*params.get<mapnik::value_integer>("height",256)), scale_factor_(*params.get<mapnik::value_double>("scale_factor",1.0)), preview_(*params.get<std::string>("preview","")) { boost::optional<std::string> map = params.get<std::string>("map"); if (!map) { throw std::runtime_error("please provide a --map=<path to xml> arg"); } xml_ = *map; boost::optional<std::string> ext = params.get<std::string>("extent"); if (ext && !ext->empty()) { if (!extent_.from_string(*ext)) throw std::runtime_error("could not parse `extent` string" + *ext); } /* else { throw std::runtime_error("please provide a --extent=<minx,miny,maxx,maxy> arg"); }*/ }
ogr_featureset::ogr_featureset(mapnik::context_ptr const& ctx, OGRLayer & layer, mapnik::box2d<double> const& extent, std::string const& encoding) : ctx_(ctx), layer_(layer), layerdef_(layer.GetLayerDefn()), tr_(new transcoder(encoding)), fidcolumn_(layer_.GetFIDColumn()), count_(0) { layer_.SetSpatialFilterRect (extent.minx(), extent.miny(), extent.maxx(), extent.maxy()); }
static void query_extent(boost::shared_ptr<sqlite_resultset> rs, mapnik::box2d<double>& extent) { bool first = true; while (rs->is_valid() && rs->step_next()) { int size; const char* data = static_cast<const char*>(rs->column_blob(0, size)); if (data) { boost::ptr_vector<mapnik::geometry_type> paths; mapnik::geometry_utils::from_wkb(paths, data, size, mapnik::wkbAuto); for (unsigned i=0; i<paths.size(); ++i) { mapnik::box2d<double> const& bbox = paths[i].envelope(); if (bbox.valid()) { if (first) { first = false; extent = bbox; } else { extent.expand_to_include(bbox); } } } } } }
bool operator()() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon_vertex_adapter<double> va(poly); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; // NOTE: this rewind is critical otherwise // agg_conv_adapter_vpgen will give garbage // values for the first vertex clipped.rewind(0); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } unsigned expected_count = 30; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
void shape_io::read_bbox(shape_file::record_type & record, mapnik::box2d<double> & bbox) { double lox = record.read_double(); double loy = record.read_double(); double hix = record.read_double(); double hiy = record.read_double(); bbox.init(lox, loy, hix, hiy); }
featureset_ptr geos_datasource::features(query const& q) const { #ifdef MAPNIK_STATS mapnik::progress_timer __stats__(std::clog, "geos_datasource::features"); #endif const mapnik::box2d<double> extent = q.get_bbox(); std::ostringstream s; s << "POLYGON((" << extent.minx() << " " << extent.miny() << "," << extent.maxx() << " " << extent.miny() << "," << extent.maxx() << " " << extent.maxy() << "," << extent.minx() << " " << extent.maxy() << "," << extent.minx() << " " << extent.miny() << "))"; MAPNIK_LOG_DEBUG(geos) << "geos_datasource: Using extent=" << s.str(); return boost::make_shared<geos_featureset>(*geometry_, GEOSGeomFromWKT(s.str().c_str()), geometry_id_, geometry_data_, geometry_data_name_, desc_.get_encoding()); }
featureset_ptr geos_datasource::features(query const& q) const { if (!is_bound_) bind(); const mapnik::box2d<double> extent = q.get_bbox(); std::ostringstream s; s << "POLYGON((" << extent.minx() << " " << extent.miny() << "," << extent.maxx() << " " << extent.miny() << "," << extent.maxx() << " " << extent.maxy() << "," << extent.minx() << " " << extent.maxy() << "," << extent.minx() << " " << extent.miny() << "))"; #ifdef MAPNIK_DEBUG clog << "GEOS Plugin: using extent: " << s.str() << endl; #endif return boost::make_shared<geos_featureset>(*geometry_, GEOSGeomFromWKT(s.str().c_str()), geometry_id_, geometry_data_, geometry_data_name_, desc_.get_encoding(), multiple_geometries_); }
box2d<double> get_buffered_extent() const { double extra = 2.0 * scale() * buffer_size_; box2d<double> ext(extent_); double extra_width = extent_.width() + extra; double extra_height = extent_.height() + extra; if (extra_width < 0.0) { extra_width = 0.0; } if (extra_height < 0.0) { extra_height = 0.0; } ext.width(extra_width); ext.height(extra_height); return ext; }
bool validate() const { std::string expected_wkt("Polygon((212 134,329 138,394 229,528 178,631 234.4,631 321.3,559 466,463 324,421 446,315 340,233 454,181 286.7,181 238.2,200 264,183 228),(313 190,229 191,249 334,343 287,405 378,455 262,553 397,613 263,533 237,510 305,470 248,440 256))"); boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); if (paths.size() != 1) { std::clog << "paths.size() != 1\n"; return false; } mapnik::geometry_type const& geom = paths[0]; mapnik::vertex_adapter va(geom); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { geom2.push_vertex(x,y,(mapnik::CommandType)cmd); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; auto env = mapnik::envelope(geom); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(geom2,env,expect); } render(geom2,env,actual); return benchmark::compare_images(actual,expect); }
bool operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; for (mapnik::geometry_type const& geom : paths) { mapnik::vertex_adapter va(geom); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); clipped.rewind(0); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } } unsigned expected_count = 29; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
bool operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; for (mapnik::geometry_type const& geom : paths) { mapnik::vertex_adapter va(geom); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; // NOTE: this rewind is critical otherwise // agg_conv_adapter_vpgen will give garbage // values for the first vertex clipped.rewind(0); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } } unsigned expected_count = 31; if (count != expected_count) { std::clog << "test1: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
void operator()() const { boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } for (unsigned i=0;i<iterations_;++i) { for (mapnik::geometry_type & geom : paths) { conv_clip clipped(geom); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) {} } } }
std::vector<unsigned> bboxToXYZ(mapnik::box2d<double> const& bboxCoords) { double minx = bboxCoords.minx(); double miny = bboxCoords.miny(); double maxx = bboxCoords.maxx(); double maxy = bboxCoords.maxy(); mapnik::merc2lonlat(&minx,&miny,1); mapnik::merc2lonlat(&maxx,&maxy,1); std::vector<double> ubbox = { minx, miny, maxx, maxy }; unsigned z = getBboxZoom(ubbox); if (z == 0) return {0, 0, 0}; minx = pointToTile(minx, miny, 32)[0]; miny = pointToTile(minx, miny, 32)[1]; unsigned x = static_cast<unsigned>(minx); unsigned y = static_cast<unsigned>(miny); return {x, y, z}; }
bool validate() const { std::string expected_wkt("Polygon((181 286.666667,233 454,315 340,421 446,463 324,559 466,631 321.320755,631 234.386861,528 178,394 229,329 138,212 134,183 228,200 264,181 238.244444),(313 190,440 256,470 248,510 305,533 237,613 263,553 397,455 262,405 378,343 287,249 334,229 191,313 190,313 190))"); boost::ptr_vector<mapnik::geometry_type> paths; if (!mapnik::from_wkt(wkt_in_, paths)) { throw std::runtime_error("Failed to parse WKT"); } if (paths.size() != 1) { std::clog << "paths.size() != 1\n"; return false; } mapnik::geometry_type & geom = paths[0]; conv_clip clipped(geom); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); unsigned cmd; double x,y; mapnik::geometry_type geom2(mapnik::geometry_type::types::Polygon); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { geom2.push_vertex(x,y,(mapnik::CommandType)cmd); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; if (!mapnik::util::exists(expect)) { std::clog << "generating expected image: " << expect << "\n"; render(geom2,geom.envelope(),expect); } render(geom2,geom.envelope(),actual); return benchmark::compare_images(actual,expect); }
bool validate() const { mapnik::Map m(width_,height_); mapnik::load_map(m,xml_,true); if (extent_.valid()) { m.zoom_to_box(extent_); } else { m.zoom_all(); } mapnik::image_rgba8 im(m.width(),m.height()); mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_); ren.apply(); if (!preview_.empty()) { std::clog << "preview available at " << preview_ << "\n"; mapnik::save_to_file(im,preview_); } return true; }
bool operator()() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double> >()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom); mapnik::geometry::correct(poly); mapnik::geometry::linear_ring<double> bbox; bbox.emplace_back(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny()); bool valid = true; for (unsigned i=0;i<iterations_;++i) { std::deque<mapnik::geometry::polygon<double> > result; boost::geometry::intersection(bbox, poly, result); unsigned count = 0; for (auto const& _geom : result) { mapnik::geometry::polygon_vertex_adapter<double> va(_geom); unsigned cmd; double x,y; while ((cmd = va.vertex(&x, &y)) != mapnik::SEG_END) { ++count; } unsigned expected_count = 29; if (count != expected_count) { std::clog << "test3: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } } return valid; }
bool operator()() const { if (!preview_.empty()) { return false; } mapnik::Map m(width_,height_); mapnik::load_map(m,xml_); if (extent_.valid()) { m.zoom_to_box(extent_); } else { m.zoom_all(); } for (unsigned i=0;i<iterations_;++i) { mapnik::image_rgba8 im(m.width(),m.height()); mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_); ren.apply(); } return true; }
bool validate() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double> >()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom); mapnik::geometry::correct(poly); mapnik::geometry::linear_ring<double> bbox; bbox.emplace_back(extent_.minx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.maxy()); bbox.emplace_back(extent_.maxx(), extent_.miny()); bbox.emplace_back(extent_.minx(), extent_.miny()); std::deque<mapnik::geometry::polygon<double> > result; boost::geometry::intersection(bbox, poly, result); std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; mapnik::geometry::multi_polygon<double> mp; for (auto const& _geom: result) { //std::clog << boost::geometry::dsv(geom) << "\n"; mp.emplace_back(_geom); } mapnik::geometry::geometry<double> geom2(mp); auto env = mapnik::geometry::envelope(geom2); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(mp,env,expect); } render(mp,env,actual); return benchmark::compare_images(actual,expect); }
static bool detect_extent(std::shared_ptr<sqlite_connection> ds, bool has_spatial_index, mapnik::box2d<double> & extent, std::string const& index_table, std::string const& metadata, std::string const& geometry_field, std::string const& geometry_table, std::string const& key_field, std::string const& table ) { if (! metadata.empty()) { std::ostringstream s; s << "SELECT xmin, ymin, xmax, ymax FROM " << metadata; s << " WHERE LOWER(f_table_name) = LOWER('" << geometry_table << "')"; MAPNIK_LOG_DEBUG(sqlite) << "sqlite_datasource: executing: '" << s.str() << "'"; std::shared_ptr<sqlite_resultset> rs(ds->execute_query(s.str())); if (rs->is_valid() && rs->step_next()) { double xmin = rs->column_double(0); double ymin = rs->column_double(1); double xmax = rs->column_double(2); double ymax = rs->column_double(3); extent.init (xmin, ymin, xmax, ymax); return true; } } else if (has_spatial_index) { std::ostringstream s; s << "SELECT MIN(xmin), MIN(ymin), MAX(xmax), MAX(ymax) FROM " << index_table; MAPNIK_LOG_DEBUG(sqlite) << "sqlite_datasource: executing: '" << s.str() << "'"; std::shared_ptr<sqlite_resultset> rs(ds->execute_query(s.str())); if (rs->is_valid() && rs->step_next()) { if (! rs->column_isnull(0)) { double xmin = rs->column_double(0); double ymin = rs->column_double(1); double xmax = rs->column_double(2); double ymax = rs->column_double(3); extent.init (xmin, ymin, xmax, ymax); return true; } } } else if (! key_field.empty()) { std::ostringstream s; s << "SELECT " << geometry_field << "," << key_field << " FROM (" << table << ")"; MAPNIK_LOG_DEBUG(sqlite) << "sqlite_datasource: executing: '" << s.str() << "'"; std::shared_ptr<sqlite_resultset> rs(ds->execute_query(s.str())); sqlite_utils::query_extent(rs,extent); return true; } return false; }
featureset_ptr sqlite_datasource::features_at_point(coord2d const& pt) const { if (!is_bound_) bind(); if (dataset_) { // TODO - need tolerance mapnik::box2d<double> const e(pt.x,pt.y,pt.x,pt.y); std::ostringstream s; s << "SELECT " << geometry_field_ << "," << key_field_; std::vector<attribute_descriptor>::const_iterator itr = desc_.get_descriptors().begin(); std::vector<attribute_descriptor>::const_iterator end = desc_.get_descriptors().end(); while (itr != end) { std::string fld_name = itr->get_name(); if (fld_name != key_field_) s << ",\"" << itr->get_name() << "\""; ++itr; } s << " FROM "; std::string query (table_); if (use_spatial_index_) { std::ostringstream spatial_sql; spatial_sql << std::setprecision(16); spatial_sql << " WHERE " << key_field_ << " IN (SELECT pkid FROM idx_" << geometry_table_ << "_" << geometry_field_; spatial_sql << " WHERE xmax>=" << e.minx() << " AND xmin<=" << e.maxx() ; spatial_sql << " AND ymax>=" << e.miny() << " AND ymin<=" << e.maxy() << ")"; if (boost::algorithm::ifind_first(query, "WHERE")) { boost::algorithm::ireplace_first(query, "WHERE", spatial_sql.str() + " AND "); } else if (boost::algorithm::ifind_first(query, geometry_table_)) { boost::algorithm::ireplace_first(query, table_, table_ + " " + spatial_sql.str()); } } s << query ; if (row_limit_ > 0) { s << " LIMIT " << row_limit_; } if (row_offset_ > 0) { s << " OFFSET " << row_offset_; } #ifdef MAPNIK_DEBUG std::clog << "Sqlite Plugin: " << s.str() << std::endl; #endif boost::shared_ptr<sqlite_resultset> rs (dataset_->execute_query (s.str())); return boost::make_shared<sqlite_featureset>(rs, desc_.get_encoding(), format_, multiple_geometries_); } return featureset_ptr(); }
bool validate() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); agg::path_storage ps; ps.move_to(extent_.minx(), extent_.miny()); ps.line_to(extent_.minx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.maxy()); ps.line_to(extent_.maxx(), extent_.miny()); ps.close_polygon(); mapnik::geometry::polygon_vertex_adapter<double> va(poly); poly_clipper clipped(va,ps, agg::clipper_and, agg::clipper_non_zero, agg::clipper_non_zero, 1); unsigned cmd; double x,y; clipped.rewind(0); mapnik::geometry::polygon<double> poly2; mapnik::geometry::linear_ring<double> ring; // TODO: handle resulting multipolygon // exterior ring while (true) { cmd = clipped.vertex(&x, &y); ring.add_coord(x,y); if (cmd == mapnik::SEG_CLOSE) break; } poly2.set_exterior_ring(std::move(ring)); // interior ring ring.clear(); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { ring.add_coord(x,y); } poly2.add_hole(std::move(ring)); mapnik::geometry::correct(poly2); std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; mapnik::geometry::multi_polygon<double> mp; mp.emplace_back(poly2); auto env = mapnik::geometry::envelope(mp); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(mp,env,expect); } render(mp,env,actual); return benchmark::compare_images(actual,expect); }
bool validate() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double> >()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> & poly = mapnik::util::get<mapnik::geometry::polygon<double> >(geom); mapnik::geometry::correct(poly); ClipperLib::Clipper clipper; mapnik::geometry::line_string<std::int64_t> path; for (auto const& pt : poly.exterior_ring) { double x = pt.x; double y = pt.y; path.emplace_back(static_cast<ClipperLib::cInt>(x),static_cast<ClipperLib::cInt>(y)); } if (!clipper.AddPath(path, ClipperLib::ptSubject, true)) { std::clog << "ptSubject ext failed!\n"; } for (auto const& ring : poly.interior_rings) { path.clear(); for (auto const& pt : ring) { double x = pt.x; double y = pt.y; path.emplace_back(static_cast<ClipperLib::cInt>(x),static_cast<ClipperLib::cInt>(y)); } if (!clipper.AddPath(path, ClipperLib::ptSubject, true)) { std::clog << "ptSubject ext failed!\n"; } } std::cerr << "path size=" << path.size() << std::endl; mapnik::geometry::line_string<std::int64_t> clip_box; clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.miny())); clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.maxx()),static_cast<ClipperLib::cInt>(extent_.miny())); clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.maxx()),static_cast<ClipperLib::cInt>(extent_.maxy())); clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.maxy())); clip_box.emplace_back(static_cast<ClipperLib::cInt>(extent_.minx()),static_cast<ClipperLib::cInt>(extent_.miny())); if (!clipper.AddPath( clip_box, ClipperLib::ptClip, true )) { std::clog << "ptClip failed!\n"; } ClipperLib::PolyTree polygons; clipper.Execute(ClipperLib::ctIntersection, polygons, ClipperLib::pftNonZero, ClipperLib::pftNonZero); clipper.Clear(); ClipperLib::PolyNode* polynode = polygons.GetFirst(); mapnik::geometry::multi_polygon<double> mp; mp.emplace_back(); bool first = true; while (polynode) { if (!polynode->IsHole()) { if (first) first = false; else mp.emplace_back(); // start new polygon for (auto const& pt : polynode->Contour) { mp.back().exterior_ring.add_coord(pt.x, pt.y); } // childrens are interior rings for (auto const* ring : polynode->Childs) { mapnik::geometry::linear_ring<double> hole; for (auto const& pt : ring->Contour) { hole.add_coord(pt.x, pt.y); } mp.back().add_hole(std::move(hole)); } } polynode = polynode->GetNext(); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; mapnik::geometry::geometry<double> geom2(mp); auto env = mapnik::geometry::envelope(geom2); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(mp,env,expect); } render(mp,env,actual); return benchmark::compare_images(actual,expect); }
minx, miny, maxx, maxy }; unsigned z = getBboxZoom(ubbox); if (z == 0) return {0, 0, 0}; minx = pointToTile(minx, miny, 32)[0]; miny = pointToTile(minx, miny, 32)[1]; unsigned x = static_cast<unsigned>(minx); unsigned y = static_cast<unsigned>(miny); return {x, y, z}; } TEST_CASE( "vector tile projection 1", "should support z/x/y to bbox conversion at 0/0/0" ) { mapnik::box2d<double> map_extent = mapnik::vector_tile_impl::tile_mercator_bbox(0,0,0); mapnik::box2d<double> e(-20037508.342789,-20037508.342789,20037508.342789,20037508.342789); double epsilon = 0.000001; CHECK(std::fabs(map_extent.minx() - e.minx()) < epsilon); CHECK(std::fabs(map_extent.miny() - e.miny()) < epsilon); CHECK(std::fabs(map_extent.maxx() - e.maxx()) < epsilon); CHECK(std::fabs(map_extent.maxy() - e.maxy()) < epsilon); auto xyz = bboxToXYZ(map_extent); /* CHECK(xyz[0] == 0); CHECK(xyz[1] == 0); CHECK(xyz[2] == 0); */ } TEST_CASE( "vector tile projection 2", "should support z/x/y to bbox conversion up to z33" ) {
static inline void set(mapnik::box2d<CoordinateType> &b , ct const& value) { b.set_maxy(value); }
static inline ct get(mapnik::box2d<double> const& b) { return b.maxy();}
bool validate() const { mapnik::geometry::geometry<double> geom; if (!mapnik::from_wkt(wkt_in_, geom)) { throw std::runtime_error("Failed to parse WKT"); } if (mapnik::geometry::is_empty(geom)) { std::clog << "empty geom!\n"; return false; } if (!geom.is<mapnik::geometry::polygon<double>>()) { std::clog << "not a polygon!\n"; return false; } mapnik::geometry::polygon<double> const& poly = mapnik::util::get<mapnik::geometry::polygon<double>>(geom); mapnik::geometry::polygon_vertex_adapter<double> va(poly); conv_clip clipped(va); clipped.clip_box( extent_.minx(), extent_.miny(), extent_.maxx(), extent_.maxy()); clipped.rewind(0); mapnik::geometry::polygon<double> poly2; mapnik::geometry::linear_ring<double> ring; // exterior ring unsigned cmd; double x, y, x0, y0; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { if (cmd == mapnik::SEG_MOVETO) { x0 = x; y0 = y; } if (cmd == mapnik::SEG_CLOSE) { ring.emplace_back(x0, y0); break; } ring.emplace_back(x,y); } poly2.push_back(std::move(ring)); // interior rings ring.clear(); while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { if (cmd == mapnik::SEG_MOVETO) { x0 = x; y0 = y; } else if (cmd == mapnik::SEG_CLOSE) { ring.emplace_back(x0,y0); poly2.push_back(std::move(ring)); ring.clear(); continue; } ring.emplace_back(x,y); } std::string expect = expected_+".png"; std::string actual = expected_+"_actual.png"; mapnik::geometry::multi_polygon<double> mp; mp.emplace_back(poly2); auto env = mapnik::geometry::envelope(mp); if (!mapnik::util::exists(expect) || (std::getenv("UPDATE") != nullptr)) { std::clog << "generating expected image: " << expect << "\n"; render(mp,env,expect); } render(mp,env,actual); return benchmark::compare_images(actual,expect); }
static inline void set(mapnik::box2d<double> &b , ct const& value) { b.set_maxy(value); }
static inline ct get(mapnik::box2d<CoordinateType> const& b) { return b.maxy();}