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_); }
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"); } 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(); for (unsigned i=0;i<iterations_;++i) { for (mapnik::geometry_type & geom : paths) { poly_clipper clipped(geom,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) {} } } }
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()); }
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 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); }
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> const& 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(); bool valid = true; for (unsigned i=0;i<iterations_;++i) { unsigned count = 0; 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); clipped.rewind(0); unsigned cmd; double x,y; while ((cmd = clipped.vertex(&x, &y)) != mapnik::SEG_END) { count++; } unsigned expected_count = 31; if (count != expected_count) { std::clog << "test2: clipping failed: processed " << count << " verticies but expected " << expected_count << "\n"; valid = false; } } return valid; }
static bool apply_spatial_filter(std::string & query, mapnik::box2d<double> const& e, std::string const& table, std::string const& key_field, std::string const& index_table, std::string const& geometry_table, std::string const& intersects_token) { std::ostringstream spatial_sql; spatial_sql << std::setprecision(16); spatial_sql << key_field << " IN (SELECT pkid FROM " << index_table; 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, intersects_token)) { boost::algorithm::ireplace_all(query, intersects_token, spatial_sql.str()); return true; } // substitute first WHERE found if not using JOIN // (because we can't know the WHERE is on the right table) else if (boost::algorithm::ifind_first(query, "WHERE") && !boost::algorithm::ifind_first(query, "JOIN")) { std::string replace(" WHERE " + spatial_sql.str() + " AND "); boost::algorithm::ireplace_first(query, "WHERE", replace); return true; } // fallback to appending spatial filter at end of query else if (boost::algorithm::ifind_first(query, geometry_table)) { query = table + " WHERE " + spatial_sql.str(); return true; } return false; }
static jobject box2dFromNative(JNIEnv *env, mapnik::box2d<double> const& box) { jobject ret=env->AllocObject(CLASS_BOX2D); env->SetDoubleField(ret, FIELD_BOX2D_MINX, box.minx()); env->SetDoubleField(ret, FIELD_BOX2D_MINY, box.miny()); env->SetDoubleField(ret, FIELD_BOX2D_MAXX, box.maxx()); env->SetDoubleField(ret, FIELD_BOX2D_MAXY, box.maxy()); return ret; }
std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::geometry_type & geom) { using line_clipper = agg::conv_clip_polyline<mapnik::geometry_type>; line_clipper clipped(geom); clipped.clip_box(bbox.minx(),bbox.miny(),bbox.maxx(),bbox.maxy()); return dump_path(clipped); }
std::string clip_line(mapnik::box2d<double> const& bbox, mapnik::path_type const& path) { using line_clipper = agg::conv_clip_polyline<mapnik::vertex_adapter>; mapnik::vertex_adapter va(path); line_clipper clipped(va); clipped.clip_box(bbox.minx(),bbox.miny(),bbox.maxx(),bbox.maxy()); return dump_path(clipped); }
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); }
void bind(mapnik::box2d<double> const& bbox) { if ((sqlite3_bind_double(stmt_, 2, bbox.minx()) != SQLITE_OK) || (sqlite3_bind_double(stmt_, 3, bbox.maxx()) != SQLITE_OK) || (sqlite3_bind_double(stmt_, 4, bbox.miny()) != SQLITE_OK) || (sqlite3_bind_double(stmt_, 5, bbox.maxy()) != SQLITE_OK)) { throw mapnik::datasource_exception("SQLite Plugin: invalid value for for extent while generating index"); } }
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 validate() const { mapnik::projection src(src_,defer_proj4_init_); mapnik::projection dest(dest_,defer_proj4_init_); mapnik::proj_transform tr(src,dest); mapnik::box2d<double> bbox = from_; if (!tr.forward(bbox)) return false; return ((std::fabs(bbox.minx() - to_.minx()) < .5) && (std::fabs(bbox.maxx() - to_.maxx()) < .5) && (std::fabs(bbox.miny() - to_.miny()) < .5) && (std::fabs(bbox.maxy() - to_.maxy()) < .5) ); }
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()), // TODO - unused count_(0) { layer_.SetSpatialFilterRect (extent.minx(), extent.miny(), extent.maxx(), extent.maxy()); }
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; }
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; }
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}; }
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) {} } } }
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); }
static inline ct get(mapnik::box2d<double> const& b) { return b.miny();}
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); }
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 ct get(mapnik::box2d<CoordinateType> const& b) { return b.miny();}
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(); }
}; 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" ) { int x = 2145960701; int y = 1428172928; int z = 32; mapnik::box2d<double> map_extent = mapnik::vector_tile_impl::tile_mercator_bbox(x,y,z);