diff --git a/CHANGELOG.md b/CHANGELOG.md index a2becf50a..9f78fdd27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,10 @@ Summary: The 2.2.0 release is the fastest running and most stable release in the - Fixed blurry rendering of image and SVG icons (#1316) +- Added detection of invalid srs values when loading xml (#646) + +- Removed muffling of projection errors while rendering (#646) + - Improved logging system (https://github.com/mapnik/mapnik/wiki/Logging) - Added support for reading images from in memory streams (#1805) diff --git a/include/mapnik/feature_style_processor_impl.hpp b/include/mapnik/feature_style_processor_impl.hpp index bd7653ae2..2e8222551 100644 --- a/include/mapnik/feature_style_processor_impl.hpp +++ b/include/mapnik/feature_style_processor_impl.hpp @@ -160,36 +160,29 @@ void feature_style_processor::apply(double scale_denom) Processor & p = static_cast(*this); p.start_map_processing(m_); - try - { - projection proj(m_.srs(),true); - if (scale_denom <= 0.0) - scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic()); - scale_denom *= scale_factor_; + projection proj(m_.srs(),true); + if (scale_denom <= 0.0) + scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic()); + scale_denom *= scale_factor_; - BOOST_FOREACH ( layer const& lyr, m_.layers() ) + BOOST_FOREACH ( layer const& lyr, m_.layers() ) + { + if (lyr.visible(scale_denom)) { - if (lyr.visible(scale_denom)) - { - std::set names; - apply_to_layer(lyr, - p, - proj, - m_.scale(), - scale_denom, - m_.width(), - m_.height(), - m_.get_current_extent(), - m_.buffer_size(), - names); + std::set names; + apply_to_layer(lyr, + p, + proj, + m_.scale(), + scale_denom, + m_.width(), + m_.height(), + m_.get_current_extent(), + m_.buffer_size(), + names); - } } } - catch (proj_init_error const& ex) - { - MAPNIK_LOG_ERROR(feature_style_processor) << "feature_style_processor: proj_init_error=" << ex.what(); - } p.end_map_processing(m_); @@ -207,30 +200,23 @@ void feature_style_processor::apply(mapnik::layer const& lyr, { Processor & p = static_cast(*this); p.start_map_processing(m_); - try - { - projection proj(m_.srs(),true); - if (scale_denom <= 0.0) - scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic()); - scale_denom *= scale_factor_; + projection proj(m_.srs(),true); + if (scale_denom <= 0.0) + scale_denom = mapnik::scale_denominator(m_.scale(),proj.is_geographic()); + scale_denom *= scale_factor_; - if (lyr.visible(scale_denom)) - { - apply_to_layer(lyr, - p, - proj, - m_.scale(), - scale_denom, - m_.width(), - m_.height(), - m_.get_current_extent(), - m_.buffer_size(), - names); - } - } - catch (proj_init_error const& ex) + if (lyr.visible(scale_denom)) { - MAPNIK_LOG_ERROR(feature_style_processor) << "feature_style_processor: proj_init_error=" << ex.what(); + apply_to_layer(lyr, + p, + proj, + m_.scale(), + scale_denom, + m_.width(), + m_.height(), + m_.get_current_extent(), + m_.buffer_size(), + names); } p.end_map_processing(m_); } diff --git a/src/load_map.cpp b/src/load_map.cpp index 5b5698ab6..8dcf8df28 100644 --- a/src/load_map.cpp +++ b/src/load_map.cpp @@ -199,7 +199,17 @@ void map_parser::parse_map(Map & map, xml_node const& pt, std::string const& bas map.set_background_image(ensure_relative_to_xml(image_filename)); } - map.set_srs(map_node.get_attr("srs", map.srs())); + std::string srs = map_node.get_attr("srs", map.srs()); + try + { + // create throwaway projection object here to ensure it is valid + projection proj(srs); + } + catch (proj_init_error const& ex) + { + throw mapnik::config_error(ex.what()); + } + map.set_srs(srs); optional buffer_size = map_node.get_opt_attr("buffer-size"); if (buffer_size) @@ -543,9 +553,17 @@ void map_parser::parse_layer(Map & map, xml_node const& node) { name = node.get_attr("name", std::string("Unnamed")); - // XXX if no projection is given inherit from map? [DS] + // If no projection is given inherit from map std::string srs = node.get_attr("srs", map.srs()); - + try + { + // create throwaway projection object here to ensure it is valid + projection proj(srs); + } + catch (proj_init_error const& ex) + { + throw mapnik::config_error(ex.what()); + } layer lyr(name, srs); optional status = node.get_opt_attr("status"); diff --git a/tests/data/broken_maps/invalid_layer_srs.xml b/tests/data/broken_maps/invalid_layer_srs.xml new file mode 100644 index 000000000..2fbc25fc8 --- /dev/null +++ b/tests/data/broken_maps/invalid_layer_srs.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/tests/data/broken_maps/invalid_map_srs.xml b/tests/data/broken_maps/invalid_map_srs.xml new file mode 100644 index 000000000..16dbf335d --- /dev/null +++ b/tests/data/broken_maps/invalid_map_srs.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file