artemp/mapnik — Issue #506: Add a Map level custom extent or max_extent to enhance clipping ability
Author: artemp
Created: 2011-10-11 16:22:55+00:00
State: open
Labels: Core_Library

Based on discussion here:

http://lists.berlios.de/pipermail/mapnik-devel/2010-January/001044.html

Related tickets: #308,#402

Background: BoundsClipping

Working patch from David:
{{{
#!diff
diff -NbaurX scripts/from_trunk.exclude_sh.txt mapnik.0.7.1528/include/mapnik/feature_style_processor.hpp mapnik/include/mapnik/feature_style_processor.hpp
--- mapnik.0.7.1528/include/mapnik/feature_style_processor.hpp	2010-01-09 18:27:34.000000000 -0700
+++ mapnik/include/mapnik/feature_style_processor.hpp	2010-01-09 18:33:38.000000000 -0700
@@ -121,15 +121,23 @@
boost::shared_ptr ds=lay.datasource();
if (ds)
{
- Envelope ext = m_.get_buffered_extent();
projection proj1(lay.srs());
proj_transform prj_trans(proj0,proj1);

- double mx0 = ext.minx();
- double my0 = ext.miny();
+ Envelope ext = m_.get_buffered_extent();
+ Envelope all = m_.getAllLayersExtent();
+
+ // limit the buffered extents to the extents of all layers
+ if ( ext.minx() > all.maxx() || ext.maxx() < all.minx() || ext.miny() > all.maxy() || ext.maxy() < all.miny() )
+ {
+ return; // no intersection
+ }
+
+ double mx0 = (all.minx() < ext.minx())? ext.minx(): all.minx();
+ double my0 = (all.miny() < ext.miny())? ext.miny(): all.miny();
double mz0 = 0.0;
- double mx1 = ext.maxx();
- double my1 = ext.maxy();
+ double mx1 = (all.maxx() > ext.maxx())? ext.maxx(): all.maxx();
+ double my1 = (all.maxy() > ext.maxy())? ext.maxy(): all.maxy();
double mz1 = 0.0;

// project main map projection into layers extent
diff -NbaurX scripts/from_trunk.exclude_sh.txt mapnik.0.7.1528/include/mapnik/map.hpp mapnik/include/mapnik/map.hpp
--- mapnik.0.7.1528/include/mapnik/map.hpp	2010-01-09 18:27:34.000000000 -0700
+++ mapnik/include/mapnik/map.hpp	2010-01-09 18:34:49.000000000 -0700
@@ -78,6 +78,7 @@
std::vector layers_;
aspect_fix_mode aspectFixMode_;
Envelope currentExtent_;
+ Envelope allLayersExtent_;

public:

@@ -300,6 +301,13 @@

void pan_and_zoom(int x,int y,double zoom);

+ void setAllLayersExtent();
+
+ /*! \brief Get current bounding box encompassinag all layers.
+ * @return The current bounding box encompassinag all layers.
+ */
+ const Envelope& getAllLayersExtent() const;
+
/*! \brief Get current bounding box.
* @return The current bounding box.
*/
diff -NbaurX scripts/from_trunk.exclude_sh.txt mapnik.0.7.1528/src/load_map.cpp mapnik/src/load_map.cpp
--- mapnik.0.7.1528/src/load_map.cpp	2010-01-09 18:27:40.000000000 -0700
+++ mapnik/src/load_map.cpp	2010-01-09 18:35:45.000000000 -0700
@@ -120,6 +120,7 @@
#endif
map_parser parser( strict, filename);
parser.parse_map(map, pt);
+ map.setAllLayersExtent();
}

void load_map_string(Map & map, std::string const& str, bool strict, std::string const& base_url)
@@ -141,6 +142,7 @@

map_parser parser( strict, base_url);
parser.parse_map(map, pt);
+ map.setAllLayersExtent();
}

void map_parser::parse_map( Map & map, ptree const & pt )
diff -NbaurX scripts/from_trunk.exclude_sh.txt mapnik.0.7.1528/src/map.cpp mapnik/src/map.cpp
--- mapnik.0.7.1528/src/map.cpp	2010-01-09 18:27:40.000000000 -0700
+++ mapnik/src/map.cpp	2010-01-09 18:37:10.000000000 -0700
@@ -280,6 +280,54 @@
fixAspectRatio();
}

+ void Map::setAllLayersExtent()
+ {
+ try
+ {
+ projection proj0(srs_);
+ bool first = true;
+ std::vector::const_iterator itr = layers_.begin();
+ std::vector::const_iterator end = layers_.end();
+ while (itr != end)
+ {
+ std::string const& layer_srs = itr->srs();
+ projection proj1(layer_srs);
+ proj_transform prj_trans(proj0,proj1);
+
+ Envelope layerExt = itr->envelope();
+ double x0 = layerExt.minx();
+ double y0 = layerExt.miny();
+ double z0 = 0.0;
+ double x1 = layerExt.maxx();
+ double y1 = layerExt.maxy();
+ double z1 = 0.0;
+ prj_trans.backward(x0,y0,z0);
+ prj_trans.backward(x1,y1,z1);
+
+ Envelope layerExt2(x0,y0,x1,y1);
+#ifdef MAPNIK_DEBUG
+ std::clog << " layer1 - > " << layerExt << "\n";
+ std::clog << " layer2 - > " << layerExt2 << "\n";
+#endif
+ if (first)
+ {
+ allLayersExtent_ = layerExt2;
+ first = false;
+ }
+ else
+ {
+ allLayersExtent_.expand_to_include(layerExt2);
+ }
+ ++itr;
+ }
+ }
+ catch (proj_init_error & ex)
+ {
+ std::clog << "proj_init_error:" << ex.what() << '\n';
+ }
+ }
+
+
void Map::zoom_all()
{
try
@@ -388,6 +436,12 @@
}
}

+ const Envelope& Map::getAllLayersExtent() const
+ {
+ return allLayersExtent_;
+ }
+
+
const Envelope& Map::getCurrentExtent() const
{
return currentExtent_;
}}}