format utils

This commit is contained in:
Mathis Logemann 2022-01-26 20:41:37 +01:00
parent e7c3d04309
commit d5a873e81c
14 changed files with 630 additions and 595 deletions

View file

@ -20,7 +20,6 @@
*
*****************************************************************************/
#include <iostream>
#include <string>
@ -31,11 +30,9 @@
#include <mapnik/datasource_cache.hpp>
#include <mapnik/util/geometry_to_wkb.hpp>
int main (int argc, char ** argv )
int main(int argc, char** argv)
{
if ( argc !=2)
if (argc != 2)
{
std::cerr << "Usage: " << argv[0] << " <path-to-shapefile>\n";
return EXIT_SUCCESS;
@ -57,8 +54,7 @@ int main (int argc, char ** argv )
try
{
ds = mapnik::datasource_cache::instance().create(p);
}
catch ( ... )
} catch (...)
{
std::cerr << "Can't create datasource!\n";
return EXIT_FAILURE;
@ -78,25 +74,23 @@ int main (int argc, char ** argv )
mapnik::featureset_ptr fs = ds->features(q);
mapnik::feature_ptr f = fs->next();
while(f)
while (f)
{
std::cerr << *f << std::endl;
mapnik::geometry::geometry<double> const& geom = f->get_geometry();
// NDR
{
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::wkbNDR);
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(),wkb->size()) << std::endl;
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom, mapnik::wkbNDR);
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(), wkb->size()) << std::endl;
}
// XDR
{
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::wkbXDR);
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(),wkb->size()) << std::endl;
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom, mapnik::wkbXDR);
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(), wkb->size()) << std::endl;
}
f = fs->next();
}
}
return EXIT_SUCCESS;
}

View file

@ -42,25 +42,25 @@ MAPNIK_DISABLE_WARNING_POP
const int DEFAULT_DEPTH = 8;
const double DEFAULT_RATIO = 0.55;
namespace mapnik { namespace detail {
namespace mapnik {
namespace detail {
bool is_csv(std::string const& filename)
{
return boost::iends_with(filename,".csv")
|| boost::iends_with(filename,".tsv");
return boost::iends_with(filename, ".csv") || boost::iends_with(filename, ".tsv");
}
bool is_geojson(std::string const& filename)
{
return boost::iends_with(filename,".geojson")
|| boost::iends_with(filename,".json");
return boost::iends_with(filename, ".geojson") || boost::iends_with(filename, ".json");
}
}}
} // namespace detail
} // namespace mapnik
int main (int argc, char** argv)
int main(int argc, char** argv)
{
//using namespace mapnik;
// using namespace mapnik;
namespace po = boost::program_options;
bool verbose = false;
bool validate_features = false;
@ -76,6 +76,7 @@ int main (int argc, char** argv)
try
{
po::options_description desc("Mapnik CSV/GeoJSON index utility");
// clang-format off
desc.add_options()
("help,h", "Produce usage message")
("version,V","Print version string")
@ -89,14 +90,15 @@ int main (int argc, char** argv)
("validate-features", "Validate GeoJSON features")
("bbox,b", po::value<std::string>(), "Only index features within bounding box: --bbox=minx,miny,maxx,maxy")
;
// clang-format on
po::positional_options_description p;
p.add("files",-1);
p.add("files", -1);
po::store(po::command_line_parser(argc, argv)
.options(desc)
.style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise)
.positional(p)
.run(), vm);
.options(desc)
.style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise)
.positional(p)
.run(),
vm);
po::notify(vm);
if (vm.count("version"))
@ -139,14 +141,13 @@ int main (int argc, char** argv)
}
if (vm.count("files"))
{
files=vm["files"].as<std::vector<std::string> >();
files = vm["files"].as<std::vector<std::string>>();
}
if (vm.count("bbox") && bbox.from_string(vm["bbox"].as<std::string>()))
{
use_bbox = true;
}
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << "Error: " << ex.what() << std::endl;
return EXIT_FAILURE;
@ -203,7 +204,7 @@ int main (int argc, char** argv)
else if (mapnik::detail::is_geojson(filename))
{
std::clog << "processing '" << filename << "' as GeoJSON\n";
std::pair<bool,mapnik::box2d<float>> result;
std::pair<bool, mapnik::box2d<float>> result;
result = mapnik::detail::process_geojson_file_x3(boxes, filename, validate_features, verbose);
if (!result.first)
{
@ -221,9 +222,9 @@ int main (int argc, char** argv)
for (auto const& item : boxes)
{
auto ext_f = std::get<0>(item);
if (use_bbox && !bbox.intersects(ext_f)) continue;
mapnik::util::index_record rec =
{std::get<1>(item).first, std::get<1>(item).second, ext_f};
if (use_bbox && !bbox.intersects(ext_f))
continue;
mapnik::util::index_record rec = {std::get<1>(item).first, std::get<1>(item).second, ext_f};
tree.insert(rec, ext_f);
}
@ -231,8 +232,7 @@ int main (int argc, char** argv)
std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
if (!file)
{
std::clog << "cannot open index file for writing file \""
<< (filename + ".index") << "\"" << std::endl;
std::clog << "cannot open index file for writing file \"" << (filename + ".index") << "\"" << std::endl;
}
else
{

View file

@ -36,10 +36,12 @@
#include <iostream>
#include <sstream>
namespace mapnik { namespace detail {
namespace mapnik {
namespace detail {
template <typename T>
std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
template<typename T>
std::pair<bool, typename T::value_type::first_type>
process_csv_file(T& boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote)
{
using box_type = typename T::value_type::first_type;
csv_utils::csv_file_parser p;
@ -47,14 +49,12 @@ std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, s
p.separator_ = separator;
p.quote_ = quote;
util::mapped_memory_file csv_file{filename};
try
{
p.parse_csv_and_boxes(csv_file.file(), boxes);
return std::make_pair(true, box_type(p.extent_));
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << ex.what() << std::endl;
return std::make_pair(false, box_type(p.extent_));
@ -64,6 +64,7 @@ std::pair<bool,typename T::value_type::first_type> process_csv_file(T & boxes, s
using box_type = mapnik::box2d<float>;
using item_type = std::pair<box_type, std::pair<std::uint64_t, std::uint64_t>>;
using boxes_type = std::vector<item_type>;
template std::pair<bool,box_type> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
template std::pair<bool, box_type> process_csv_file(boxes_type&, std::string const&, std::string const&, char, char);
}}
} // namespace detail
} // namespace mapnik

View file

@ -26,11 +26,17 @@
#include <utility>
#include <mapnik/geometry/box2d.hpp>
namespace mapnik { namespace detail {
namespace mapnik {
namespace detail {
template <typename T>
std::pair<bool, typename T::value_type::first_type> process_csv_file(T & boxes, std::string const& filename, std::string const& manual_headers, char separator, char quote);
template<typename T>
std::pair<bool, typename T::value_type::first_type> process_csv_file(T& boxes,
std::string const& filename,
std::string const& manual_headers,
char separator,
char quote);
}}
}
} // namespace mapnik
#endif // MAPNIK_UTILS_PROCESS_CSV_FILE_HPP

View file

@ -43,35 +43,34 @@ MAPNIK_DISABLE_WARNING_POP
namespace {
constexpr mapnik::json::well_known_names feature_properties[] = {
mapnik::json::well_known_names::type,
mapnik::json::well_known_names::geometry,
mapnik::json::well_known_names::properties}; // sorted
constexpr mapnik::json::well_known_names feature_properties[] = {mapnik::json::well_known_names::type,
mapnik::json::well_known_names::geometry,
mapnik::json::well_known_names::properties}; // sorted
constexpr mapnik::json::well_known_names geometry_properties[] = {
mapnik::json::well_known_names::type,
mapnik::json::well_known_names::coordinates}; // sorted
mapnik::json::well_known_names::type,
mapnik::json::well_known_names::coordinates}; // sorted
constexpr mapnik::json::well_known_names geometry_collection_properties[] = {
mapnik::json::well_known_names::type,
mapnik::json::well_known_names::geometries}; // sorted
mapnik::json::well_known_names::type,
mapnik::json::well_known_names::geometries}; // sorted
template <typename Keys>
template<typename Keys>
std::string join(Keys const& keys)
{
std::string result;
bool first = true;
for (auto const& key : keys)
{
if (!first) result += ",";
if (!first)
result += ",";
result += "\"" + std::string(mapnik::json::wkn_to_string(key)) + "\"";
first = false;
}
return result;
}
template <typename Iterator, typename Keys>
template<typename Iterator, typename Keys>
bool has_keys(Iterator first1, Iterator last1, Keys const& keys)
{
auto first2 = std::begin(keys);
@ -86,55 +85,57 @@ bool has_keys(Iterator first1, Iterator last1, Keys const& keys)
return true;
}
template <typename Keys>
bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& keys, bool verbose)
template<typename Keys>
bool validate_geojson_feature(mapnik::json::geojson_value& value, Keys const& keys, bool verbose)
{
if (!value.is<mapnik::json::geojson_object>())
{
if (verbose) std::clog << "Expecting an GeoJSON object" << std::endl;
if (verbose)
std::clog << "Expecting an GeoJSON object" << std::endl;
return false;
}
mapnik::json::geojson_object & feature = mapnik::util::get<mapnik::json::geojson_object>(value);
std::sort(feature.begin(), feature.end(), [](auto const& e0, auto const& e1)
{
return std::get<0>(e0) < std::get<0>(e1);
});
mapnik::json::geojson_object& feature = mapnik::util::get<mapnik::json::geojson_object>(value);
std::sort(feature.begin(), feature.end(), [](auto const& e0, auto const& e1) {
return std::get<0>(e0) < std::get<0>(e1);
});
if (!has_keys(feature.begin(), feature.end(), feature_properties))
{
if (verbose) std::clog << "Expecting one of " << join(feature_properties) << std::endl;
if (verbose)
std::clog << "Expecting one of " << join(feature_properties) << std::endl;
return false;
}
for (auto & elem : feature)
for (auto& elem : feature)
{
auto const key = std::get<0>(elem);
if (key == mapnik::json::well_known_names::geometry)
{
auto & geom_value = std::get<1>(elem);
auto& geom_value = std::get<1>(elem);
if (!geom_value.is<mapnik::json::geojson_object>())
{
if (verbose) std::clog << "\"geometry\": xxx <-- expecting an JSON object here" << std::endl;
if (verbose)
std::clog << "\"geometry\": xxx <-- expecting an JSON object here" << std::endl;
return false;
}
auto & geometry = mapnik::util::get<mapnik::json::geojson_object>(geom_value);
auto& geometry = mapnik::util::get<mapnik::json::geojson_object>(geom_value);
// sort by property name
std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1)
{
return std::get<0>(e0) < std::get<0>(e1);
});
std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1) {
return std::get<0>(e0) < std::get<0>(e1);
});
if (!has_keys(geometry.begin(), geometry.end(), geometry_properties)
&& !has_keys(geometry.begin(), geometry.end(), geometry_collection_properties))
if (!has_keys(geometry.begin(), geometry.end(), geometry_properties) &&
!has_keys(geometry.begin(), geometry.end(), geometry_collection_properties))
{
if (verbose) std::clog << "\"geometry\": xxx <-- expecting one of " << join(geometry_properties)
<< " or " << join(geometry_collection_properties) << std::endl;
if (verbose)
std::clog << "\"geometry\": xxx <-- expecting one of " << join(geometry_properties) << " or "
<< join(geometry_collection_properties) << std::endl;
return false;
}
mapnik::geometry::geometry_types geom_type;
mapnik::json::positions const* coordinates = nullptr;
for (auto & elem2 : geometry)
for (auto& elem2 : geometry)
{
auto const key2 = std::get<0>(elem2);
if (key2 == mapnik::json::well_known_names::type)
@ -142,13 +143,16 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
auto const& geom_type_value = std::get<1>(elem2);
if (!geom_type_value.is<mapnik::geometry::geometry_types>())
{
if (verbose) std::clog << "\"type\": xxx <-- expecting an GeoJSON geometry type here" << std::endl;
if (verbose)
std::clog << "\"type\": xxx <-- expecting an GeoJSON geometry type here" << std::endl;
return false;
}
geom_type = mapnik::util::get<mapnik::geometry::geometry_types>(geom_type_value);
if (geom_type == mapnik::geometry::geometry_types::GeometryCollection)
{
if (verbose) std::clog << "GeometryCollections are not allowed" << std::endl;;
if (verbose)
std::clog << "GeometryCollections are not allowed" << std::endl;
;
return false;
}
}
@ -157,7 +161,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
auto const& coordinates_value = std::get<1>(elem2);
if (!coordinates_value.is<mapnik::json::positions>())
{
if (verbose) std::clog << "\"coordinates\": xxx <-- expecting an GeoJSON positions here" << std::endl;
if (verbose)
std::clog << "\"coordinates\": xxx <-- expecting an GeoJSON positions here" << std::endl;
return false;
}
coordinates = &mapnik::util::get<mapnik::json::positions>(coordinates_value);
@ -168,7 +173,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
// expecting single position
if (!coordinates->is<mapnik::json::point>())
{
if (verbose) std::clog << "Expecting single position in Point" << std::endl;
if (verbose)
std::clog << "Expecting single position in Point" << std::endl;
return false;
}
}
@ -177,7 +183,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
// expecting
if (!coordinates->is<mapnik::json::ring>())
{
if (verbose) std::clog << "Expecting sequence of positions (ring) in LineString" << std::endl;
if (verbose)
std::clog << "Expecting sequence of positions (ring) in LineString" << std::endl;
return false;
}
else
@ -185,7 +192,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
auto const& ring = mapnik::util::get<mapnik::json::ring>(*coordinates);
if (ring.size() < 2)
{
if (verbose) std::clog << "Expecting at least two coordinates in LineString" << std::endl;
if (verbose)
std::clog << "Expecting at least two coordinates in LineString" << std::endl;
return false;
}
}
@ -195,7 +203,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
// expecting
if (!coordinates->is<mapnik::json::rings>())
{
if (verbose) std::clog << "Expecting an array of rings in Polygon" << std::endl;
if (verbose)
std::clog << "Expecting an array of rings in Polygon" << std::endl;
return false;
}
else
@ -203,14 +212,16 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
auto const& rings = mapnik::util::get<mapnik::json::rings>(*coordinates);
if (rings.size() < 1)
{
if (verbose) std::clog << "Expecting at least one ring in Polygon" << std::endl;
if (verbose)
std::clog << "Expecting at least one ring in Polygon" << std::endl;
return false;
}
for (auto const& ring : rings)
{
if (ring.size() < 4)
{
if (verbose) std::clog << "Expecting at least four coordinates in Polygon ring" << std::endl;
if (verbose)
std::clog << "Expecting at least four coordinates in Polygon ring" << std::endl;
return false;
}
}
@ -227,20 +238,20 @@ using base_iterator_type = char const*;
auto const& geojson_value = mapnik::json::grammar::geojson_value;
}
} // namespace
namespace mapnik { namespace detail {
namespace mapnik {
namespace detail {
template <typename T>
std::pair<bool,typename T::value_type::first_type> process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose)
template<typename T>
std::pair<bool, typename T::value_type::first_type>
process_geojson_file_x3(T& boxes, std::string const& filename, bool validate_features, bool verbose)
{
using box_type = typename T::value_type::first_type;
box_type extent;
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
mapnik::mapped_region_ptr mapped_region;
boost::optional<mapnik::mapped_region_ptr> memory =
mapnik::mapped_memory_cache::instance().find(filename, true);
boost::optional<mapnik::mapped_region_ptr> memory = mapnik::mapped_memory_cache::instance().find(filename, true);
if (!memory)
{
std::clog << "Error : cannot memory map " << filename << std::endl;
@ -269,17 +280,16 @@ std::pair<bool,typename T::value_type::first_type> process_geojson_file_x3(T & b
try
{
mapnik::json::extract_bounding_boxes(itr, end, boxes);
}
catch (boost::spirit::x3::expectation_failure<base_iterator_type> const& ex)
} catch (boost::spirit::x3::expectation_failure<base_iterator_type> const& ex)
{
std::clog << ex.what() << std::endl;
std::clog << "Expected: " << ex.which();
std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << '"' << std::endl;
return std::make_pair(false, extent);
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'" << std::endl;
std::clog << "mapnik-index (GeoJSON) : could not extract bounding boxes from : '" << filename << "'"
<< std::endl;
return std::make_pair(false, extent);
}
@ -287,18 +297,18 @@ std::pair<bool,typename T::value_type::first_type> process_geojson_file_x3(T & b
using space_type = mapnik::json::grammar::space_type;
auto keys = mapnik::json::get_keys();
#if BOOST_VERSION >= 106700
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(keys)
[ geojson_value ];
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(keys)[geojson_value];
#else
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(std::ref(keys))
[ geojson_value ];
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(std::ref(keys))[geojson_value];
#endif
for (auto const& item : boxes)
{
if (item.first.valid())
{
if (!extent.valid()) extent = item.first;
else extent.expand_to_include(item.first);
if (!extent.valid())
extent = item.first;
else
extent.expand_to_include(item.first);
if (validate_features)
{
base_iterator_type feat_itr = start + item.second.first;
@ -309,36 +319,43 @@ std::pair<bool,typename T::value_type::first_type> process_geojson_file_x3(T & b
bool result = x3::phrase_parse(feat_itr, feat_end, feature_grammar, space_type(), feature_value);
if (!result || feat_itr != feat_end)
{
if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl;
if (verbose)
std::clog << "Failed to parse: offset=" << item.second.first
<< " size=" << item.second.second << std::endl;
return std::make_pair(false, extent);
}
}
catch (x3::expectation_failure<std::string::const_iterator> const& ex)
} catch (x3::expectation_failure<std::string::const_iterator> const& ex)
{
if (verbose) std::clog << ex.what() << std::endl;
if (verbose)
std::clog << ex.what() << std::endl;
return std::make_pair(false, extent);
}
catch (...)
} catch (...)
{
if (verbose) std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second << std::endl;
if (verbose)
std::clog << "Failed to parse: offset=" << item.second.first << " size=" << item.second.second
<< std::endl;
return std::make_pair(false, extent);
}
if (!validate_geojson_feature(feature_value, keys, verbose))
{
if (verbose) std::clog << "Failed to validate: [" << std::string(start + item.second.first, feat_end ) << "]" << std::endl;
if (verbose)
std::clog << "Failed to validate: [" << std::string(start + item.second.first, feat_end) << "]"
<< std::endl;
return std::make_pair(false, extent);
}
}
}
else if (validate_features)
{
if (verbose) std::clog << "Invalid bbox encountered " << item.first << std::endl;
if (verbose)
std::clog << "Invalid bbox encountered " << item.first << std::endl;
return std::make_pair(false, extent);
}
}
return std::make_pair(true, extent);
}
template std::pair<bool,box_type> process_geojson_file_x3(boxes_type&, std::string const&, bool, bool);
template std::pair<bool, box_type> process_geojson_file_x3(boxes_type&, std::string const&, bool, bool);
}}
} // namespace detail
} // namespace mapnik

View file

@ -26,11 +26,14 @@
#include <utility>
#include <string>
namespace mapnik { namespace detail {
namespace mapnik {
namespace detail {
template <typename T>
std::pair<bool, typename T::value_type::first_type> process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose);
template<typename T>
std::pair<bool, typename T::value_type::first_type>
process_geojson_file_x3(T& boxes, std::string const& filename, bool validate_features, bool verbose);
}}
}
} // namespace mapnik
#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP

View file

@ -17,7 +17,7 @@ MAPNIK_DISABLE_WARNING_POP
#include <string>
int main (int argc,char** argv)
int main(int argc, char** argv)
{
namespace po = boost::program_options;
@ -36,6 +36,7 @@ int main (int argc,char** argv)
try
{
po::options_description desc("mapnik-render utility");
// clang-format off
desc.add_options()
("help,h", "produce usage message")
("version,V","print version string")
@ -48,17 +49,17 @@ int main (int argc,char** argv)
("map-height",po::value<int>(),"map height in pixels")
("variables","make map parameters available as render-time variables")
;
// clang-format on
po::positional_options_description p;
p.add("xml",1);
p.add("img",1);
p.add("xml", 1);
p.add("img", 1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("version"))
{
std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
std::clog << "version " << MAPNIK_VERSION_STRING << std::endl;
return 1;
}
@ -80,7 +81,7 @@ int main (int argc,char** argv)
if (vm.count("xml"))
{
xml_file=vm["xml"].as<std::string>();
xml_file = vm["xml"].as<std::string>();
}
else
{
@ -90,7 +91,7 @@ int main (int argc,char** argv)
if (vm.count("img"))
{
img_file=vm["img"].as<std::string>();
img_file = vm["img"].as<std::string>();
}
else
{
@ -100,7 +101,7 @@ int main (int argc,char** argv)
if (vm.count("scale-factor"))
{
scale_factor=vm["scale-factor"].as<double>();
scale_factor = vm["scale-factor"].as<double>();
}
if (vm.count("variables"))
@ -108,21 +109,23 @@ int main (int argc,char** argv)
params_as_variables = true;
}
if (vm.count("map-width")) {
map_width = vm["map-width"].as<int>();
if (vm.count("map-width"))
{
map_width = vm["map-width"].as<int>();
}
if (vm.count("map-height")) {
map_height = vm["map-height"].as<int>();
if (vm.count("map-height"))
{
map_height = vm["map-height"].as<int>();
}
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
mapnik::freetype_engine::register_fonts("./fonts",true);
mapnik::Map map(map_width,map_height);
mapnik::load_map(map,xml_file,true);
mapnik::freetype_engine::register_fonts("./fonts", true);
mapnik::Map map(map_width, map_height);
mapnik::load_map(map, xml_file, true);
map.zoom_all();
mapnik::image_rgba8 im(map.width(),map.height());
mapnik::request req(map.width(),map.height(),map.get_current_extent());
mapnik::image_rgba8 im(map.width(), map.height());
mapnik::request req(map.width(), map.height(), map.get_current_extent());
req.set_buffer_size(map.buffer_size());
mapnik::attributes vars;
if (params_as_variables)
@ -148,9 +151,9 @@ int main (int argc,char** argv)
}
}
}
mapnik::agg_renderer<mapnik::image_rgba8> ren(map,req,vars,im,scale_factor,0,0);
mapnik::agg_renderer<mapnik::image_rgba8> ren(map, req, vars, im, scale_factor, 0, 0);
ren.apply();
mapnik::save_to_file(im,img_file);
mapnik::save_to_file(im, img_file);
if (auto_open)
{
std::ostringstream s;
@ -170,8 +173,7 @@ int main (int argc,char** argv)
{
std::clog << "rendered to: " << img_file << "\n";
}
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << "Error " << ex.what() << std::endl;
return -1;

View file

@ -20,7 +20,6 @@
*
*****************************************************************************/
#include <iostream>
#include <vector>
#include <string>
@ -45,25 +44,26 @@ using mapnik::datasource_exception;
const int MAXDEPTH = 64;
const int DEFAULT_DEPTH = 8;
const double MINRATIO=0.5;
const double MAXRATIO=0.8;
const double DEFAULT_RATIO=0.55;
const double MINRATIO = 0.5;
const double MAXRATIO = 0.8;
const double DEFAULT_RATIO = 0.55;
int main (int argc,char** argv)
int main(int argc, char** argv)
{
using namespace mapnik;
namespace po = boost::program_options;
using std::string;
using std::vector;
bool verbose=false;
unsigned int depth=DEFAULT_DEPTH;
double ratio=DEFAULT_RATIO;
bool verbose = false;
unsigned int depth = DEFAULT_DEPTH;
double ratio = DEFAULT_RATIO;
vector<string> ogr_files;
try
{
po::options_description desc("ogrindex utility");
// clang-format off
desc.add_options()
("help,h", "produce usage message")
("version,V", "print version string")
@ -72,16 +72,16 @@ int main (int argc,char** argv)
("ratio,r", po::value<double>(), "split ratio (default 0.55)")
("ogr_files", po::value<vector<string> >(), "ogr supported files to index: file1 file2 ...fileN")
;
// clang-format on
po::positional_options_description p;
p.add("ogr_files",-1);
p.add("ogr_files", -1);
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
po::notify(vm);
if (vm.count("version"))
{
std::clog<<"version 0.1.0" <<std::endl;
std::clog << "version 0.1.0" << std::endl;
return 1;
}
if (vm.count("help"))
@ -99,10 +99,9 @@ int main (int argc,char** argv)
}
if (vm.count("ogr_files"))
{
ogr_files=vm["ogr_files"].as< vector<string> >();
ogr_files = vm["ogr_files"].as<vector<string>>();
}
}
catch (...)
} catch (...)
{
std::clog << "Exception of unknown type!" << std::endl;
return -1;
@ -121,9 +120,9 @@ int main (int argc,char** argv)
{
std::clog << "processing " << *itr << std::endl;
std::string ogrname (*itr++);
std::string ogrname(*itr++);
if (! mapnik::util::exists (ogrname))
if (!mapnik::util::exists(ogrname))
{
std::clog << "error : file " << ogrname << " doesn't exists" << std::endl;
continue;
@ -131,11 +130,12 @@ int main (int argc,char** argv)
// TODO - layer names don't match dataset name, so this will break for
// any layer types of ogr than shapefiles, etc
size_t breakpoint = ogrname.find_last_of (".");
if (breakpoint == string::npos) breakpoint = ogrname.length();
std::string ogrlayername (ogrname.substr(0, breakpoint));
size_t breakpoint = ogrname.find_last_of(".");
if (breakpoint == string::npos)
breakpoint = ogrname.length();
std::string ogrlayername(ogrname.substr(0, breakpoint));
if (mapnik::util::exists (ogrlayername + ".ogrindex"))
if (mapnik::util::exists(ogrlayername + ".ogrindex"))
{
std::clog << "error : " << ogrlayername << ".ogrindex file already exists for " << ogrname << std::endl;
continue;
@ -144,24 +144,23 @@ int main (int argc,char** argv)
mapnik::parameters params;
params["type"] = "ogr";
params["file"] = ogrname;
//unsigned first = 0;
params["layer_by_index"] = 0;//ogrlayername;
// unsigned first = 0;
params["layer_by_index"] = 0; // ogrlayername;
try
{
ogr_datasource ogr (params);
ogr_datasource ogr(params);
box2d<double> extent = ogr.envelope();
quadtree<int> tree (extent, depth, ratio);
int count=0;
quadtree<int> tree(extent, depth, ratio);
int count = 0;
std::clog << "file:" << ogrname << std::endl;
std::clog << "layer:" << ogrlayername << std::endl;
std::clog << "extent:" << extent << std::endl;
mapnik::query q (extent, 1.0);
mapnik::featureset_ptr itr = ogr.features (q);
mapnik::query q(extent, 1.0);
mapnik::featureset_ptr itr = ogr.features(q);
while (true)
{
@ -173,8 +172,9 @@ int main (int argc,char** argv)
box2d<double> item_ext = fp->envelope();
tree.insert (count, item_ext);
if (verbose) {
tree.insert(count, item_ext);
if (verbose)
{
std::clog << "record number " << (count + 1) << " box=" << item_ext << std::endl;
}
@ -183,14 +183,17 @@ int main (int argc,char** argv)
std::clog << " number shapes=" << count << std::endl;
std::fstream file((ogrlayername+".ogrindex").c_str(),
std::fstream file((ogrlayername + ".ogrindex").c_str(),
std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
if (!file) {
std::clog << "cannot open ogrindex file for writing file \""
<< (ogrlayername+".ogrindex") << "\"" << std::endl;
} else {
if (!file)
{
std::clog << "cannot open ogrindex file for writing file \"" << (ogrlayername + ".ogrindex") << "\""
<< std::endl;
}
else
{
tree.trim();
std::clog<<" number nodes="<<tree.count()<<std::endl;
std::clog << " number nodes=" << tree.count() << std::endl;
file.exceptions(std::ios::failbit | std::ios::badbit);
tree.write(file);
file.flush();
@ -198,7 +201,7 @@ int main (int argc,char** argv)
}
}
// catch problem at the datasource creation
catch (const mapnik::datasource_exception & ex )
catch (const mapnik::datasource_exception& ex)
{
std::clog << ex.what() << "\n";
return -1;
@ -206,10 +209,10 @@ int main (int argc,char** argv)
catch (...)
{
std::clog << "unknown exception..." << "\n";
std::clog << "unknown exception..."
<< "\n";
return -1;
}
}
std::clog << "done!" << std::endl;

View file

@ -35,20 +35,20 @@ MAPNIK_DISABLE_WARNING_POP
#include <memory>
//stl
// stl
#include <iostream>
#include <fstream>
#include <exception>
int main ( int argc, char** argv)
int main(int argc, char** argv)
{
namespace po = boost::program_options;
po::options_description desc("Postgresql/PostGIS to SQLite3 converter\n Options");
std::string usage = "usage: pgsql2sqlite --dbname db --table planet_osm_line --file osm.sqlite --query \"select * from planet_osm_line\"";
std::string usage = "usage: pgsql2sqlite --dbname db --table planet_osm_line --file osm.sqlite --query \"select * "
"from planet_osm_line\"";
try
{
// clang-format off
desc.add_options()
("help,?","Display this help screen.")
("host,h",po::value<std::string>(),"Allows you to specify connection to a database on a machine other than the default.")
@ -61,13 +61,13 @@ int main ( int argc, char** argv)
("file,f",po::value<std::string>(),"Use this option to specify the name of the file to create.")
;
//po::positional_options_description p;
//p.add("table",1);
// clang-format on
// po::positional_options_description p;
// p.add("table",1);
po::variables_map vm;
//positional(p)
po::store(po::command_line_parser(argc,argv).options(desc).run(),vm);
// positional(p)
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
po::notify(vm);
if (vm.count("help"))
@ -76,7 +76,7 @@ int main ( int argc, char** argv)
std::cout << usage << "\n";
return EXIT_SUCCESS;
}
else if ( !vm.count("dbname") || !vm.count("file") || !vm.count("query") )
else if (!vm.count("dbname") || !vm.count("file") || !vm.count("query"))
{
std::cout << desc << "\n";
std::cout << usage << "\n";
@ -98,20 +98,20 @@ int main ( int argc, char** argv)
std::shared_ptr<Connection> conn(creator());
std::string query = vm["query"].as<std::string>();
std::string output_table_name = vm.count("table") ? vm["table"].as<std::string>() : mapnik::sql_utils::table_from_sql(query);
std::string output_table_name =
vm.count("table") ? vm["table"].as<std::string>() : mapnik::sql_utils::table_from_sql(query);
std::string output_file = vm["file"].as<std::string>();
std::cout << "output_table : " << output_table_name << "\n";
mapnik::pgsql2sqlite(conn,query,output_table_name,output_file);
}
catch (mapnik::datasource_exception & ex)
mapnik::pgsql2sqlite(conn, query, output_table_name, output_file);
} catch (mapnik::datasource_exception& ex)
{
std::cerr << ex.what() << "\n";
return EXIT_FAILURE;
}
}
catch(std::exception& e) {
} catch (std::exception& e)
{
std::cerr << desc << "\n";
std::cout << usage << "\n";
std::cerr << e.what() << "\n";

View file

@ -41,7 +41,7 @@ MAPNIK_DISABLE_WARNING_PUSH
#include <boost/algorithm/string.hpp>
MAPNIK_DISABLE_WARNING_POP
//st
// st
#include <cstdint>
#include <iostream>
#include <fstream>
@ -50,21 +50,22 @@ MAPNIK_DISABLE_WARNING_POP
static std::string numeric2string(const char* buf)
{
std::int16_t ndigits = int2net(buf);
std::int16_t weight = int2net(buf+2);
std::int16_t sign = int2net(buf+4);
std::int16_t dscale = int2net(buf+6);
std::int16_t weight = int2net(buf + 2);
std::int16_t sign = int2net(buf + 4);
std::int16_t dscale = int2net(buf + 6);
const std::unique_ptr<std::int16_t[]> digits(new std::int16_t[ndigits]);
for (int n=0; n < ndigits ;++n)
for (int n = 0; n < ndigits; ++n)
{
digits[n] = int2net(buf+8+n*2);
digits[n] = int2net(buf + 8 + n * 2);
}
std::ostringstream ss;
if (sign == 0x4000) ss << "-";
if (sign == 0x4000)
ss << "-";
int i = std::max(weight,std::int16_t(0));
int i = std::max(weight, std::int16_t(0));
int d = 0;
// Each numeric "digit" is actually a value between 0000 and 9999 stored in a 16 bit field.
@ -72,7 +73,7 @@ static std::string numeric2string(const char* buf)
// Note that the last two digits show that the leading 0's are lost when the number is split.
// We must be careful to re-insert these 0's when building the string.
while ( i >= 0)
while (i >= 0)
{
if (i <= weight && d < ndigits)
{
@ -87,24 +88,24 @@ static std::string numeric2string(const char* buf)
}
else if (dig < 100)
{
ss << "00"; // 0010 - 0099
ss << "00"; // 0010 - 0099
}
else
{
ss << "0"; // 0100 - 0999;
ss << "0"; // 0100 - 0999;
}
#else
switch(digits[d])
switch (digits[d])
{
case 0 ... 9:
ss << "000"; // 0000 - 0009
break;
case 10 ... 99:
ss << "00"; // 0010 - 0099
break;
case 100 ... 999:
ss << "0"; // 0100 - 0999
break;
case 0 ... 9:
ss << "000"; // 0000 - 0009
break;
case 10 ... 99:
ss << "00"; // 0010 - 0099
break;
case 100 ... 999:
ss << "0"; // 0100 - 0999
break;
}
#endif
}
@ -113,9 +114,9 @@ static std::string numeric2string(const char* buf)
else
{
if (d == 0)
ss << "0";
ss << "0";
else
ss << "0000";
ss << "0000";
}
i--;
@ -133,22 +134,26 @@ static std::string numeric2string(const char* buf)
value = 0;
// Output up to 4 decimal digits for this value
if (dscale > 0) {
if (dscale > 0)
{
ss << (value / 1000);
value %= 1000;
dscale--;
}
if (dscale > 0) {
if (dscale > 0)
{
ss << (value / 100);
value %= 100;
dscale--;
}
if (dscale > 0) {
if (dscale > 0)
{
ss << (value / 10);
value %= 10;
dscale--;
}
if (dscale > 0) {
if (dscale > 0)
{
ss << value;
dscale--;
}
@ -159,10 +164,9 @@ static std::string numeric2string(const char* buf)
return ss.str();
}
namespace mapnik {
template <typename Connection>
template<typename Connection>
void pgsql2sqlite(Connection conn,
std::string const& query,
std::string const& output_table_name,
@ -178,26 +182,27 @@ void pgsql2sqlite(Connection conn,
select_sql << "select ";
for (int i=0; i<count; ++i)
for (int i = 0; i < count; ++i)
{
if (i!=0) select_sql << ",";
select_sql << "\"" << rs->getFieldName(i) << "\"";
if (i != 0)
select_sql << ",";
select_sql << "\"" << rs->getFieldName(i) << "\"";
}
select_sql << " from (" << query << ") as query";
std::string table_name = mapnik::sql_utils::table_from_sql(query);
std::string schema_name="";
std::string::size_type idx=table_name.find_last_of('.');
if (idx!=std::string::npos)
std::string schema_name = "";
std::string::size_type idx = table_name.find_last_of('.');
if (idx != std::string::npos)
{
schema_name=table_name.substr(0,idx);
table_name=table_name.substr(idx+1);
schema_name = table_name.substr(0, idx);
table_name = table_name.substr(idx + 1);
}
else
{
table_name=table_name.substr(0);
table_name = table_name.substr(0);
}
std::ostringstream geom_col_sql;
@ -205,7 +210,7 @@ void pgsql2sqlite(Connection conn,
geom_col_sql << "where f_table_name='" << table_name << "'";
if (schema_name.length() > 0)
{
geom_col_sql <<" and f_table_schema='"<< schema_name <<"'";
geom_col_sql << " and f_table_schema='" << schema_name << "'";
}
rs = conn->executeQuery(geom_col_sql.str());
@ -214,9 +219,9 @@ void pgsql2sqlite(Connection conn,
std::string geom_col = "UNKNOWN";
std::string geom_type = "UNKNOWN";
if ( rs->next())
if (rs->next())
{
if (!mapnik::util::string2int(rs->getValue("srid"),srid))
if (!mapnik::util::string2int(rs->getValue("srid"), srid))
{
std::clog << "could not convert srid to integer\n";
}
@ -226,7 +231,9 @@ void pgsql2sqlite(Connection conn,
// add AsBinary(<geometry_column>) modifier
std::string select_sql_str = select_sql.str();
boost::algorithm::replace_all(select_sql_str, "\"" + geom_col + "\"","ST_AsBinary(" + geom_col+") as " + geom_col);
boost::algorithm::replace_all(select_sql_str,
"\"" + geom_col + "\"",
"ST_AsBinary(" + geom_col + ") as " + geom_col);
#ifdef MAPNIK_DEBUG
std::cout << select_sql_str << "\n";
@ -235,19 +242,22 @@ void pgsql2sqlite(Connection conn,
std::ostringstream cursor_sql;
std::string cursor_name("my_cursor");
cursor_sql << "DECLARE " << cursor_name << " BINARY INSENSITIVE NO SCROLL CURSOR WITH HOLD FOR " << select_sql_str << " FOR READ ONLY";
cursor_sql << "DECLARE " << cursor_name << " BINARY INSENSITIVE NO SCROLL CURSOR WITH HOLD FOR " << select_sql_str
<< " FOR READ ONLY";
conn->execute(cursor_sql.str());
std::shared_ptr<CursorResultSet> cursor(new CursorResultSet(conn,cursor_name,10000));
std::shared_ptr<CursorResultSet> cursor(new CursorResultSet(conn, cursor_name, 10000));
unsigned num_fields = cursor->getNumFields();
if (num_fields == 0) return;
if (num_fields == 0)
return;
std::string feature_id = "fid";
std::string feature_id = "fid";
std::ostringstream create_sql;
create_sql << "create table if not exists " << output_table_name << " (" << feature_id << " INTEGER PRIMARY KEY AUTOINCREMENT,";
create_sql << "create table if not exists " << output_table_name << " (" << feature_id
<< " INTEGER PRIMARY KEY AUTOINCREMENT,";
int geometry_oid = -1;
@ -255,7 +265,7 @@ void pgsql2sqlite(Connection conn,
context_ptr ctx = std::make_shared<context_type>();
for ( unsigned pos = 0; pos < num_fields ; ++pos)
for (unsigned pos = 0; pos < num_fields; ++pos)
{
const char* field_name = cursor->getFieldName(pos);
ctx->push(field_name);
@ -264,7 +274,7 @@ void pgsql2sqlite(Connection conn,
{
create_sql << ",";
}
output_table_insert_sql +=",?";
output_table_insert_sql += ",?";
int oid = cursor->getTypeOID(pos);
if (geom_col == cursor->getFieldName(pos))
{
@ -276,54 +286,52 @@ void pgsql2sqlite(Connection conn,
create_sql << "'" << cursor->getFieldName(pos);
switch (oid)
{
case 20:
case 21:
case 23:
create_sql << "' INTEGER";
break;
case 700:
case 701:
create_sql << "' REAL";
break;
default:
create_sql << "' TEXT";
break;
case 20:
case 21:
case 23:
create_sql << "' INTEGER";
break;
case 700:
case 701:
create_sql << "' REAL";
break;
default:
create_sql << "' TEXT";
break;
}
}
}
create_sql << ");";
output_table_insert_sql +=")";
output_table_insert_sql += ")";
std::cout << "client_encoding=" << conn->client_encoding() << "\n";
std::cout << "geometry_column=" << geom_col << "(" << geom_type
<< ") srid=" << srid << " oid=" << geometry_oid << "\n";
std::cout << "geometry_column=" << geom_col << "(" << geom_type << ") srid=" << srid << " oid=" << geometry_oid
<< "\n";
db.execute("begin;");
// output table sql
db.execute(create_sql.str());
// spatial index sql
std::string spatial_index_sql = "create virtual table idx_" + output_table_name
+ "_" + geom_col + " using rtree(pkid, xmin, xmax, ymin, ymax)";
std::string spatial_index_sql =
"create virtual table idx_" + output_table_name + "_" + geom_col + " using rtree(pkid, xmin, xmax, ymin, ymax)";
db.execute(spatial_index_sql);
//blob_to_hex hex;
// blob_to_hex hex;
int pkid = 0;
std::string spatial_index_insert_sql = "insert into idx_" + output_table_name + "_"
+ geom_col + " values (?,?,?,?,?)" ;
std::string spatial_index_insert_sql =
"insert into idx_" + output_table_name + "_" + geom_col + " values (?,?,?,?,?)";
sqlite::prepared_statement spatial_index(db,spatial_index_insert_sql);
sqlite::prepared_statement spatial_index(db, spatial_index_insert_sql);
#ifdef MAPNIK_DEBUG
std::cout << output_table_insert_sql << "\n";
#endif
sqlite::prepared_statement output_table(db,output_table_insert_sql);
sqlite::prepared_statement output_table(db, output_table_insert_sql);
while (cursor->next())
{
@ -332,86 +340,81 @@ void pgsql2sqlite(Connection conn,
sqlite::record_type output_rec;
output_rec.push_back(sqlite::value_type(pkid));
bool empty_geom = true;
const char * buf = 0;
for (unsigned pos=0 ; pos < num_fields; ++pos)
const char* buf = 0;
for (unsigned pos = 0; pos < num_fields; ++pos)
{
if (! cursor->isNull(pos))
if (!cursor->isNull(pos))
{
int size=cursor->getFieldLength(pos);
int size = cursor->getFieldLength(pos);
int oid = cursor->getTypeOID(pos);
buf=cursor->getValue(pos);
buf = cursor->getValue(pos);
switch (oid)
{
case 25:
case 1042:
case 1043:
{
std::string text(buf);
boost::algorithm::replace_all(text,"'","''");
output_rec.push_back(sqlite::value_type(text));
break;
}
case 23:
output_rec.emplace_back(int4net(buf));
break;
case 21:
output_rec.emplace_back(int(int2net(buf)));
break;
case 700:
{
float val;
float4net(val,buf);
output_rec.emplace_back(double(val));
break;
}
case 701:
{
double val;
float8net(val,buf);
output_rec.emplace_back(val);
break;
}
case 1700:
{
std::string str = numeric2string(buf);
double val;
if (mapnik::util::string2double(str,val))
{
case 25:
case 1042:
case 1043: {
std::string text(buf);
boost::algorithm::replace_all(text, "'", "''");
output_rec.push_back(sqlite::value_type(text));
break;
}
case 23:
output_rec.emplace_back(int4net(buf));
break;
case 21:
output_rec.emplace_back(int(int2net(buf)));
break;
case 700: {
float val;
float4net(val, buf);
output_rec.emplace_back(double(val));
break;
}
case 701: {
double val;
float8net(val, buf);
output_rec.emplace_back(val);
break;
}
break;
}
default:
{
if (oid == geometry_oid)
{
mapnik::feature_impl feat(ctx,pkid);
mapnik::geometry::geometry<double> geom = geometry_utils::from_wkb(buf, size, wkbGeneric);
if (!mapnik::geometry::is_empty(geom))
case 1700: {
std::string str = numeric2string(buf);
double val;
if (mapnik::util::string2double(str, val))
{
box2d<double> bbox = mapnik::geometry::envelope(geom);
if (bbox.valid())
{
sqlite::record_type rec;
rec.push_back(sqlite::value_type(pkid));
rec.push_back(sqlite::value_type(bbox.minx()));
rec.push_back(sqlite::value_type(bbox.maxx()));
rec.push_back(sqlite::value_type(bbox.miny()));
rec.push_back(sqlite::value_type(bbox.maxy()));
spatial_index.insert_record(rec);
empty_geom = false;
}
output_rec.emplace_back(val);
}
output_rec.push_back(sqlite::blob(buf,size));
break;
}
else
{
output_rec.push_back(sqlite::null_type());
default: {
if (oid == geometry_oid)
{
mapnik::feature_impl feat(ctx, pkid);
mapnik::geometry::geometry<double> geom = geometry_utils::from_wkb(buf, size, wkbGeneric);
if (!mapnik::geometry::is_empty(geom))
{
box2d<double> bbox = mapnik::geometry::envelope(geom);
if (bbox.valid())
{
sqlite::record_type rec;
rec.push_back(sqlite::value_type(pkid));
rec.push_back(sqlite::value_type(bbox.minx()));
rec.push_back(sqlite::value_type(bbox.maxx()));
rec.push_back(sqlite::value_type(bbox.miny()));
rec.push_back(sqlite::value_type(bbox.maxy()));
spatial_index.insert_record(rec);
empty_geom = false;
}
}
output_rec.push_back(sqlite::blob(buf, size));
}
else
{
output_rec.push_back(sqlite::null_type());
}
break;
}
break;
}
}
}
else
@ -420,7 +423,8 @@ void pgsql2sqlite(Connection conn,
}
}
if (!empty_geom) output_table.insert_record(output_rec);
if (!empty_geom)
output_table.insert_record(output_rec);
if (pkid % 1000 == 0)
{
@ -440,4 +444,4 @@ void pgsql2sqlite(Connection conn,
std::cout << "\r vacumming";
std::cout << "\n Done!" << std::endl;
}
}
} // namespace mapnik

View file

@ -22,37 +22,38 @@
#include "sqlite.hpp"
namespace mapnik { namespace sqlite {
namespace mapnik {
namespace sqlite {
database::database(std::string const& name)
database::database(std::string const& name)
{
sqlite3* db;
int res = sqlite3_open(name.c_str(), &db);
if (res)
{
sqlite3 *db;
int res = sqlite3_open(name.c_str(), &db);
if (res)
{
sqlite3_close(db);
throw;
}
sqlite3_close(db);
throw;
}
db_ = sqlite_db(db,database_closer());
db_ = sqlite_db(db, database_closer());
#ifdef MAPNIK_DEBUG
std::cerr << "Open database " << name << "\n";
std::cerr << "Open database " << name << "\n";
#endif
}
database::~database() {}
bool database::execute(std::string const& sql)
{
char * err_msg;
int res = sqlite3_exec(db_.get(),sql.c_str(),0,0,&err_msg);
if (res != SQLITE_OK)
{
std::cerr << "SQL"<< sql << " ERR:" << err_msg << "\n";
sqlite3_free(err_msg);
return false;
}
return true;
}
}
}
database::~database() {}
bool database::execute(std::string const& sql)
{
char* err_msg;
int res = sqlite3_exec(db_.get(), sql.c_str(), 0, 0, &err_msg);
if (res != SQLITE_OK)
{
std::cerr << "SQL" << sql << " ERR:" << err_msg << "\n";
sqlite3_free(err_msg);
return false;
}
return true;
}
} // namespace sqlite
} // namespace mapnik

View file

@ -31,7 +31,7 @@ MAPNIK_DISABLE_WARNING_PUSH
#include <sqlite3.h>
MAPNIK_DISABLE_WARNING_POP
//stl
// stl
#ifdef MAPNIK_DEBUG
#include <cassert>
#endif
@ -40,154 +40,162 @@ MAPNIK_DISABLE_WARNING_POP
#include <string>
#include <vector>
namespace mapnik { namespace sqlite {
namespace mapnik {
namespace sqlite {
class database : private util::noncopyable
class database : private util::noncopyable
{
friend class prepared_statement;
struct database_closer
{
friend class prepared_statement;
struct database_closer
{
void operator () (sqlite3 * db)
{
#ifdef MAPNIK_DEBUG
std::cerr << "close database " << db << "\n";
#endif
sqlite3_close(db);
}
};
using sqlite_db = std::shared_ptr<sqlite3>;
sqlite_db db_;
public:
database(std::string const& name);
~database();
bool execute(std::string const& sql);
};
struct null_type {};
struct blob
{
blob(const char* buf, unsigned size)
: buf_(buf), size_(size) {}
const char * buf_;
unsigned size_;
};
using value_type = mapnik::util::variant<int,double,std::string, blob,null_type>;
using record_type = std::vector<value_type>;
class prepared_statement : util::noncopyable
{
struct binder
{
binder(sqlite3_stmt * stmt, unsigned index)
: stmt_(stmt), index_(index) {}
bool operator() (null_type )
{
if (sqlite3_bind_null(stmt_, index_) != SQLITE_OK)
{
std::cerr << "cannot bind nullptr\n";
return false;
}
return true;
}
bool operator() (int val)
{
if (sqlite3_bind_int(stmt_, index_ , val ) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator() (double val)
{
if (sqlite3_bind_double(stmt_, index_ , val ) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator() (std::string const& val)
{
if (sqlite3_bind_text(stmt_, index_, val.c_str(), val.length(), SQLITE_STATIC) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator() (blob const& val)
{
if (sqlite3_bind_blob(stmt_, index_, val.buf_, val.size_, SQLITE_STATIC) != SQLITE_OK)
{
std::cerr << "cannot bind BLOB\n";
return false;
}
return true;
}
sqlite3_stmt * stmt_;
unsigned index_;
};
public:
prepared_statement(database & db, std::string const& sql)
: db_(db.db_.get()), stmt_(0)
{
const char * tail;
//char * err_msg;
int res = sqlite3_prepare_v2(db_, sql.c_str(),-1, &stmt_,&tail);
if (res != SQLITE_OK)
{
std::cerr << "ERR:"<< res << "\n";
throw;
}
}
~prepared_statement()
{
int res = sqlite3_finalize(stmt_);
if (res != SQLITE_OK)
{
std::cerr << "ERR:" << res << "\n";
}
}
bool insert_record(record_type const& rec) const
void operator()(sqlite3* db)
{
#ifdef MAPNIK_DEBUG
assert( unsigned(sqlite3_bind_parameter_count(stmt_)) == rec.size());
std::cerr << "close database " << db << "\n";
#endif
record_type::const_iterator itr = rec.begin();
record_type::const_iterator end = rec.end();
int count = 1;
for (; itr!=end;++itr)
sqlite3_close(db);
}
};
using sqlite_db = std::shared_ptr<sqlite3>;
sqlite_db db_;
public:
database(std::string const& name);
~database();
bool execute(std::string const& sql);
};
struct null_type
{};
struct blob
{
blob(const char* buf, unsigned size)
: buf_(buf)
, size_(size)
{}
const char* buf_;
unsigned size_;
};
using value_type = mapnik::util::variant<int, double, std::string, blob, null_type>;
using record_type = std::vector<value_type>;
class prepared_statement : util::noncopyable
{
struct binder
{
binder(sqlite3_stmt* stmt, unsigned index)
: stmt_(stmt)
, index_(index)
{}
bool operator()(null_type)
{
if (sqlite3_bind_null(stmt_, index_) != SQLITE_OK)
{
binder op(stmt_,count++);
if (!util::apply_visitor(op,*itr))
{
return false;
}
std::cerr << "cannot bind nullptr\n";
return false;
}
sqlite3_step(stmt_);
sqlite3_reset(stmt_);
return true;
}
private:
sqlite3 * db_;
sqlite3_stmt * stmt_;
bool operator()(int val)
{
if (sqlite3_bind_int(stmt_, index_, val) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator()(double val)
{
if (sqlite3_bind_double(stmt_, index_, val) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator()(std::string const& val)
{
if (sqlite3_bind_text(stmt_, index_, val.c_str(), val.length(), SQLITE_STATIC) != SQLITE_OK)
{
std::cerr << "cannot bind " << val << "\n";
return false;
}
return true;
}
bool operator()(blob const& val)
{
if (sqlite3_bind_blob(stmt_, index_, val.buf_, val.size_, SQLITE_STATIC) != SQLITE_OK)
{
std::cerr << "cannot bind BLOB\n";
return false;
}
return true;
}
sqlite3_stmt* stmt_;
unsigned index_;
};
public:
prepared_statement(database& db, std::string const& sql)
: db_(db.db_.get())
, stmt_(0)
{
const char* tail;
// char * err_msg;
int res = sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt_, &tail);
if (res != SQLITE_OK)
{
std::cerr << "ERR:" << res << "\n";
throw;
}
}
}
~prepared_statement()
{
int res = sqlite3_finalize(stmt_);
if (res != SQLITE_OK)
{
std::cerr << "ERR:" << res << "\n";
}
}
bool insert_record(record_type const& rec) const
{
#ifdef MAPNIK_DEBUG
assert(unsigned(sqlite3_bind_parameter_count(stmt_)) == rec.size());
#endif
record_type::const_iterator itr = rec.begin();
record_type::const_iterator end = rec.end();
int count = 1;
for (; itr != end; ++itr)
{
binder op(stmt_, count++);
if (!util::apply_visitor(op, *itr))
{
return false;
}
}
sqlite3_step(stmt_);
sqlite3_reset(stmt_);
return true;
}
private:
sqlite3* db_;
sqlite3_stmt* stmt_;
};
} // namespace sqlite
} // namespace mapnik

View file

@ -44,15 +44,15 @@ const double DEFAULT_RATIO = 0.55;
#ifdef _WIN32
#define NOMINMAX
#include <windows.h>
int main ()
int main()
#else
int main (int argc,char** argv)
int main(int argc, char** argv)
#endif
{
using namespace mapnik;
namespace po = boost::program_options;
bool verbose=false;
bool verbose = false;
bool index_parts = false;
unsigned int depth = DEFAULT_DEPTH;
double ratio = DEFAULT_RATIO;
@ -61,6 +61,7 @@ int main (int argc,char** argv)
try
{
po::options_description desc("shapeindex utility");
// clang-format off
desc.add_options()
("help,h", "produce usage message")
("version,V","print version string")
@ -70,14 +71,14 @@ int main (int argc,char** argv)
("ratio,r",po::value<double>(),"split ratio (default 0.55)")
("shape_files",po::value<std::vector<std::string> >(),"shape files to index: file1 file2 ...fileN")
;
// clang-format on
po::positional_options_description p;
p.add("shape_files",-1);
p.add("shape_files", -1);
po::variables_map vm;
#ifdef _WIN32
std::vector<std::string> args;
const auto wargs = po::split_winmain(GetCommandLineW());
for( auto it = wargs.begin() + 1; it != wargs.end(); ++it )
for (auto it = wargs.begin() + 1; it != wargs.end(); ++it)
args.push_back(mapnik::utf16_to_utf8(*it));
po::store(po::command_line_parser(args).options(desc).positional(p).run(), vm);
#else
@ -115,10 +116,9 @@ int main (int argc,char** argv)
if (vm.count("shape_files"))
{
shape_files=vm["shape_files"].as< std::vector<std::string> >();
shape_files = vm["shape_files"].as<std::vector<std::string>>();
}
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << "Error: " << ex.what() << std::endl;
return EXIT_FAILURE;
@ -135,46 +135,45 @@ int main (int argc,char** argv)
for (auto const& filename : shape_files)
{
std::clog << "processing " << filename << std::endl;
std::string shapename (filename);
boost::algorithm::ireplace_last(shapename,".shp","");
std::string shapename_full (shapename + ".shp");
std::string shapename(filename);
boost::algorithm::ireplace_last(shapename, ".shp", "");
std::string shapename_full(shapename + ".shp");
std::string shxname(shapename + ".shx");
if (! mapnik::util::exists (shapename_full))
if (!mapnik::util::exists(shapename_full))
{
std::clog << "Error : file " << shapename_full << " does not exist" << std::endl;
continue;
}
if (! mapnik::util::exists(shxname))
if (!mapnik::util::exists(shxname))
{
std::clog << "Error : shapefile index file (*.shx) " << shxname << " does not exist" << std::endl;
continue;
}
shape_file shp (shapename_full);
shape_file shp(shapename_full);
if (! shp.is_open())
if (!shp.is_open())
{
std::clog << "Error : cannot open " << shapename_full << std::endl;
continue;
}
shape_file shx (shxname);
shape_file shx(shxname);
if (!shx.is_open())
{
std::clog << "Error : cannot open " << shxname << std::endl;
continue;
}
int code = shx.read_xdr_integer(); //file_code == 9994
int code = shx.read_xdr_integer(); // file_code == 9994
std::clog << code << std::endl;
shx.skip(5*4);
shx.skip(5 * 4);
int file_length=shx.read_xdr_integer();
int version=shx.read_ndr_integer();
int shape_type=shx.read_ndr_integer();
int file_length = shx.read_xdr_integer();
int version = shx.read_ndr_integer();
int shape_type = shx.read_ndr_integer();
box2d<double> extent;
shx.read_envelope(extent);
std::clog << "length=" << file_length << std::endl;
std::clog << "version=" << version << std::endl;
std::clog << "type=" << shape_type << std::endl;
@ -187,12 +186,12 @@ int main (int argc,char** argv)
}
int pos = 50;
shx.seek(pos * 2);
mapnik::box2d<float> extent_f { static_cast<float>(extent.minx()),
static_cast<float>(extent.miny()),
static_cast<float>(extent.maxx()),
static_cast<float>(extent.maxy())};
mapnik::box2d<float> extent_f{static_cast<float>(extent.minx()),
static_cast<float>(extent.miny()),
static_cast<float>(extent.maxx()),
static_cast<float>(extent.maxy())};
mapnik::quad_tree<mapnik::detail::node, mapnik::box2d<float> > tree(extent_f, depth, ratio);
mapnik::quad_tree<mapnik::detail::node, mapnik::box2d<float>> tree(extent_f, depth, ratio);
int count = 0;
if (shape_type != shape_io::shape_null)
@ -216,32 +215,35 @@ int main (int argc,char** argv)
}
shape_type = shp.read_ndr_integer();
if (shape_type == shape_io::shape_null) continue;
if (shape_type == shape_io::shape_null)
continue;
if (shape_type==shape_io::shape_point
|| shape_type==shape_io::shape_pointm
|| shape_type == shape_io::shape_pointz)
if (shape_type == shape_io::shape_point || shape_type == shape_io::shape_pointm ||
shape_type == shape_io::shape_pointz)
{
double x=shp.read_double();
double y=shp.read_double();
item_ext=box2d<double>(x,y,x,y);
double x = shp.read_double();
double y = shp.read_double();
item_ext = box2d<double>(x, y, x, y);
}
else if (index_parts &&
(shape_type == shape_io::shape_polygon || shape_type == shape_io::shape_polygonm || shape_type == shape_io::shape_polygonz
|| shape_type == shape_io::shape_polyline || shape_type == shape_io::shape_polylinem || shape_type == shape_io::shape_polylinez))
(shape_type == shape_io::shape_polygon || shape_type == shape_io::shape_polygonm ||
shape_type == shape_io::shape_polygonz || shape_type == shape_io::shape_polyline ||
shape_type == shape_io::shape_polylinem || shape_type == shape_io::shape_polylinez))
{
shp.read_envelope(item_ext);
int num_parts = shp.read_ndr_integer();
int num_points = shp.read_ndr_integer();
std::vector<int> parts;
parts.resize(num_parts);
std::for_each(parts.begin(), parts.end(), [&](int & part) { part = shp.read_ndr_integer();});
std::for_each(parts.begin(), parts.end(), [&](int& part) { part = shp.read_ndr_integer(); });
for (int k = 0; k < num_parts; ++k)
{
int start = parts[k];
int end;
if (k == num_parts - 1) end = num_points;
else end = parts[k + 1];
if (k == num_parts - 1)
end = num_points;
else
end = parts[k + 1];
mapnik::geometry::linear_ring<double> ring;
ring.reserve(end - start);
@ -258,15 +260,15 @@ int main (int argc,char** argv)
{
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
}
mapnik::box2d<float> ext_f {static_cast<float>(item_ext.minx()),
static_cast<float>(item_ext.miny()),
static_cast<float>(item_ext.maxx()),
static_cast<float>(item_ext.maxy())};
mapnik::box2d<float> ext_f{static_cast<float>(item_ext.minx()),
static_cast<float>(item_ext.miny()),
static_cast<float>(item_ext.maxx()),
static_cast<float>(item_ext.maxy())};
tree.insert(mapnik::detail::node(offset * 2, start, end, std::move(ext_f)), ext_f);
++count;
}
}
item_ext = mapnik::box2d<double>(); //invalid
item_ext = mapnik::box2d<double>(); // invalid
}
else
{
@ -279,10 +281,10 @@ int main (int argc,char** argv)
{
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
}
mapnik::box2d<float> ext_f {static_cast<float>(item_ext.minx()),
static_cast<float>(item_ext.miny()),
static_cast<float>(item_ext.maxx()),
static_cast<float>(item_ext.maxy())};
mapnik::box2d<float> ext_f{static_cast<float>(item_ext.minx()),
static_cast<float>(item_ext.miny()),
static_cast<float>(item_ext.maxx()),
static_cast<float>(item_ext.maxy())};
tree.insert(mapnik::detail::node(offset * 2, -1, 0, std::move(ext_f)), ext_f);
++count;
@ -294,14 +296,14 @@ int main (int argc,char** argv)
{
std::clog << " number shapes=" << count << std::endl;
#ifdef _WIN32
std::ofstream file(mapnik::utf8_to_utf16(shapename+".index").c_str(), std::ios::trunc | std::ios::binary);
std::ofstream file(mapnik::utf8_to_utf16(shapename + ".index").c_str(), std::ios::trunc | std::ios::binary);
#else
std::ofstream file((shapename+".index").c_str(), std::ios::trunc | std::ios::binary);
std::ofstream file((shapename + ".index").c_str(), std::ios::trunc | std::ios::binary);
#endif
if (!file)
{
std::clog << "cannot open index file for writing file \""
<< (shapename+".index") << "\"" << std::endl;
std::clog << "cannot open index file for writing file \"" << (shapename + ".index") << "\""
<< std::endl;
}
else
{

View file

@ -53,19 +53,16 @@ MAPNIK_DISABLE_WARNING_PUSH
#include "agg_scanline_u.h"
MAPNIK_DISABLE_WARNING_POP
struct main_marker_visitor
{
main_marker_visitor(std::string const& svg_name,
double scale_factor,
bool verbose,
bool auto_open)
: svg_name_(svg_name),
scale_factor_(scale_factor),
verbose_(verbose),
auto_open_(auto_open) {}
main_marker_visitor(std::string const& svg_name, double scale_factor, bool verbose, bool auto_open)
: svg_name_(svg_name)
, scale_factor_(scale_factor)
, verbose_(verbose)
, auto_open_(auto_open)
{}
int operator() (mapnik::marker_svg const& marker) const
int operator()(mapnik::marker_svg const& marker) const
{
using pixfmt = agg::pixfmt_rgba32_pre;
using renderer_base = agg::renderer_base<pixfmt>;
@ -112,19 +109,16 @@ struct main_marker_visitor
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker.get_data()->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage);
mapnik::svg::renderer_agg<
mapnik::svg_path_adapter,
mapnik::svg_attribute_type,
renderer_solid,
agg::pixfmt_rgba32_pre > svg_renderer_this(svg_path,
marker.get_data()->attributes());
mapnik::svg::
renderer_agg<mapnik::svg_path_adapter, mapnik::svg_attribute_type, renderer_solid, agg::pixfmt_rgba32_pre>
svg_renderer_this(svg_path, marker.get_data()->attributes());
svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);
std::string png_name(svg_name_);
boost::algorithm::ireplace_last(png_name,".svg",".png");
boost::algorithm::ireplace_last(png_name, ".svg", ".png");
demultiply_alpha(im);
mapnik::save_to_file<mapnik::image_rgba8>(im,png_name,"png");
mapnik::save_to_file<mapnik::image_rgba8>(im, png_name, "png");
int status = 0;
if (auto_open_)
{
@ -143,8 +137,8 @@ struct main_marker_visitor
}
// default
template <typename T>
int operator() (T const&) const
template<typename T>
int operator()(T const&) const
{
std::clog << "svg2png error: failed to process '" << svg_name_ << "'\n";
return -1;
@ -157,7 +151,7 @@ struct main_marker_visitor
bool auto_open_;
};
int main (int argc,char** argv)
int main(int argc, char** argv)
{
namespace po = boost::program_options;
@ -172,6 +166,7 @@ int main (int argc,char** argv)
try
{
po::options_description desc("svg2png utility");
// clang-format off
desc.add_options()
("help,h", "produce usage message")
("version,V","print version string")
@ -181,7 +176,7 @@ int main (int argc,char** argv)
("scale-factor", po::value<double>(), "provide scaling factor (default: 1.0)")
("svg",po::value<std::vector<std::string> >(),"svg file to read")
;
// clang-format on
po::positional_options_description p;
p.add("svg", -1);
po::variables_map vm;
@ -221,7 +216,7 @@ int main (int argc,char** argv)
}
if (vm.count("svg"))
{
svg_files=vm["svg"].as< std::vector<std::string> >();
svg_files = vm["svg"].as<std::vector<std::string>>();
}
else
{
@ -237,22 +232,21 @@ int main (int argc,char** argv)
}
while (itr != svg_files.end())
{
std::string svg_name (*itr++);
std::string svg_name(*itr++);
if (verbose)
{
std::clog << "found: " << svg_name << "\n";
}
std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false, strict);
std::shared_ptr<mapnik::marker const> marker =
mapnik::marker_cache::instance().find(svg_name, false, strict);
main_marker_visitor visitor(svg_name, scale_factor, verbose, auto_open);
status = mapnik::util::apply_visitor(visitor, *marker);
}
}
catch (std::exception const& ex)
} catch (std::exception const& ex)
{
std::clog << "Exception caught:" << ex.what() << std::endl;
return -1;
}
catch (...)
} catch (...)
{
std::clog << "Exception of unknown type!" << std::endl;
return -1;