diff --git a/CHANGELOG.md b/CHANGELOG.md index 564c9b295..efc7ccac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ Developers: Please commit along with changes. For a complete change history, see the git log. +## Future + +- Fixed zoom_all behavior when Map maximum-extent is provided. Previously maximum-extent was used outright but + now the combined layer extents will be again respected: they will be clipped to the maximum-extent if possible + and only when back-projecting fails for all layers will the maximum-extent be used as a fallback (#1473) ## Mapnik 2.1.0 diff --git a/src/map.cpp b/src/map.cpp index cd5ba2821..7e4a3f5f8 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -340,54 +340,59 @@ void Map::zoom(double factor) void Map::zoom_all() { - if (maximum_extent_) { - zoom_to_box(*maximum_extent_); - } - else + try { - try + if (!layers_.size() > 0) + return; + projection proj0(srs_); + box2d ext; + bool success = false; + bool first = true; + std::vector::const_iterator itr = layers_.begin(); + std::vector::const_iterator end = layers_.end(); + while (itr != end) { - if (!layers_.size() > 0) - return; - projection proj0(srs_); - box2d ext; - bool success = false; - bool first = true; - std::vector::const_iterator itr = layers_.begin(); - std::vector::const_iterator end = layers_.end(); - while (itr != end) + if (itr->active()) { - if (itr->active()) + std::string const& layer_srs = itr->srs(); + projection proj1(layer_srs); + proj_transform prj_trans(proj0,proj1); + box2d layer_ext = itr->envelope(); + if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS)) { - std::string const& layer_srs = itr->srs(); - projection proj1(layer_srs); - - proj_transform prj_trans(proj0,proj1); - - box2d layer_ext = itr->envelope(); - if (prj_trans.backward(layer_ext, PROJ_ENVELOPE_POINTS)) + success = true; + MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " original ext=" << itr->envelope(); + MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " transformed to map srs=" << layer_ext; + if (first) { - success = true; - - MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " original ext=" << itr->envelope(); - MAPNIK_LOG_DEBUG(map) << "map: Layer " << itr->name() << " transformed to map srs=" << layer_ext; - - if (first) - { - ext = layer_ext; - first = false; - } - else - { - ext.expand_to_include(layer_ext); - } + ext = layer_ext; + first = false; + } + else + { + ext.expand_to_include(layer_ext); } } - ++itr; } - if (success) { - zoom_to_box(ext); - } else { + ++itr; + } + if (success) + { + if (maximum_extent_) { + ext.clip(*maximum_extent_); + } + zoom_to_box(ext); + } + else + { + if (maximum_extent_) + { + MAPNIK_LOG_ERROR(map) << "could not zoom to combined layer extents" + << " so falling back to maximum-extent for zoom_all result"; + zoom_to_box(*maximum_extent_); + } + else + { std::ostringstream s; s << "could not zoom to combined layer extents " << "using zoom_all because proj4 could not " @@ -396,10 +401,10 @@ void Map::zoom_all() throw std::runtime_error(s.str()); } } - catch (proj_init_error & ex) - { - throw mapnik::config_error(std::string("Projection error during map.zoom_all: ") + ex.what()); - } + } + catch (proj_init_error & ex) + { + throw mapnik::config_error(std::string("Projection error during map.zoom_all: ") + ex.what()); } } @@ -544,7 +549,8 @@ featureset_ptr Map::query_point(unsigned index, double x, double y) const if (fs) { mapnik::box2d map_ex = current_extent_; - if (maximum_extent_) { + if (maximum_extent_) + { map_ex.clip(*maximum_extent_); } if (!prj_trans.backward(map_ex,PROJ_ENVELOPE_POINTS))