format utils
This commit is contained in:
parent
e7c3d04309
commit
d5a873e81c
14 changed files with 630 additions and 595 deletions
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -31,11 +30,9 @@
|
||||||
#include <mapnik/datasource_cache.hpp>
|
#include <mapnik/datasource_cache.hpp>
|
||||||
#include <mapnik/util/geometry_to_wkb.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";
|
std::cerr << "Usage: " << argv[0] << " <path-to-shapefile>\n";
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -57,8 +54,7 @@ int main (int argc, char ** argv )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ds = mapnik::datasource_cache::instance().create(p);
|
ds = mapnik::datasource_cache::instance().create(p);
|
||||||
}
|
} catch (...)
|
||||||
catch ( ... )
|
|
||||||
{
|
{
|
||||||
std::cerr << "Can't create datasource!\n";
|
std::cerr << "Can't create datasource!\n";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -78,25 +74,23 @@ int main (int argc, char ** argv )
|
||||||
mapnik::featureset_ptr fs = ds->features(q);
|
mapnik::featureset_ptr fs = ds->features(q);
|
||||||
mapnik::feature_ptr f = fs->next();
|
mapnik::feature_ptr f = fs->next();
|
||||||
|
|
||||||
while(f)
|
while (f)
|
||||||
{
|
{
|
||||||
std::cerr << *f << std::endl;
|
std::cerr << *f << std::endl;
|
||||||
mapnik::geometry::geometry<double> const& geom = f->get_geometry();
|
mapnik::geometry::geometry<double> const& geom = f->get_geometry();
|
||||||
// NDR
|
// NDR
|
||||||
{
|
{
|
||||||
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::wkbNDR);
|
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;
|
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(), wkb->size()) << std::endl;
|
||||||
}
|
}
|
||||||
// XDR
|
// XDR
|
||||||
{
|
{
|
||||||
mapnik::util::wkb_buffer_ptr wkb = mapnik::util::to_wkb(geom,mapnik::wkbXDR);
|
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;
|
std::cerr << mapnik::util::detail::to_hex(wkb->buffer(), wkb->size()) << std::endl;
|
||||||
}
|
}
|
||||||
f = fs->next();
|
f = fs->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,25 +42,25 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
const int DEFAULT_DEPTH = 8;
|
const int DEFAULT_DEPTH = 8;
|
||||||
const double DEFAULT_RATIO = 0.55;
|
const double DEFAULT_RATIO = 0.55;
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
bool is_csv(std::string const& filename)
|
bool is_csv(std::string const& filename)
|
||||||
{
|
{
|
||||||
return boost::iends_with(filename,".csv")
|
return boost::iends_with(filename, ".csv") || boost::iends_with(filename, ".tsv");
|
||||||
|| boost::iends_with(filename,".tsv");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_geojson(std::string const& filename)
|
bool is_geojson(std::string const& filename)
|
||||||
{
|
{
|
||||||
return boost::iends_with(filename,".geojson")
|
return boost::iends_with(filename, ".geojson") || boost::iends_with(filename, ".json");
|
||||||
|| 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;
|
namespace po = boost::program_options;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool validate_features = false;
|
bool validate_features = false;
|
||||||
|
@ -76,6 +76,7 @@ int main (int argc, char** argv)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::options_description desc("Mapnik CSV/GeoJSON index utility");
|
po::options_description desc("Mapnik CSV/GeoJSON index utility");
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "Produce usage message")
|
("help,h", "Produce usage message")
|
||||||
("version,V","Print version string")
|
("version,V","Print version string")
|
||||||
|
@ -89,14 +90,15 @@ int main (int argc, char** argv)
|
||||||
("validate-features", "Validate GeoJSON features")
|
("validate-features", "Validate GeoJSON features")
|
||||||
("bbox,b", po::value<std::string>(), "Only index features within bounding box: --bbox=minx,miny,maxx,maxy")
|
("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;
|
po::positional_options_description p;
|
||||||
p.add("files",-1);
|
p.add("files", -1);
|
||||||
po::store(po::command_line_parser(argc, argv)
|
po::store(po::command_line_parser(argc, argv)
|
||||||
.options(desc)
|
.options(desc)
|
||||||
.style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise)
|
.style(po::command_line_style::unix_style | po::command_line_style::allow_long_disguise)
|
||||||
.positional(p)
|
.positional(p)
|
||||||
.run(), vm);
|
.run(),
|
||||||
|
vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
if (vm.count("version"))
|
if (vm.count("version"))
|
||||||
|
@ -139,14 +141,13 @@ int main (int argc, char** argv)
|
||||||
}
|
}
|
||||||
if (vm.count("files"))
|
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>()))
|
if (vm.count("bbox") && bbox.from_string(vm["bbox"].as<std::string>()))
|
||||||
{
|
{
|
||||||
use_bbox = true;
|
use_bbox = true;
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception const& ex)
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
{
|
||||||
std::clog << "Error: " << ex.what() << std::endl;
|
std::clog << "Error: " << ex.what() << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -203,7 +204,7 @@ int main (int argc, char** argv)
|
||||||
else if (mapnik::detail::is_geojson(filename))
|
else if (mapnik::detail::is_geojson(filename))
|
||||||
{
|
{
|
||||||
std::clog << "processing '" << filename << "' as GeoJSON\n";
|
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);
|
result = mapnik::detail::process_geojson_file_x3(boxes, filename, validate_features, verbose);
|
||||||
if (!result.first)
|
if (!result.first)
|
||||||
{
|
{
|
||||||
|
@ -221,9 +222,9 @@ int main (int argc, char** argv)
|
||||||
for (auto const& item : boxes)
|
for (auto const& item : boxes)
|
||||||
{
|
{
|
||||||
auto ext_f = std::get<0>(item);
|
auto ext_f = std::get<0>(item);
|
||||||
if (use_bbox && !bbox.intersects(ext_f)) continue;
|
if (use_bbox && !bbox.intersects(ext_f))
|
||||||
mapnik::util::index_record rec =
|
continue;
|
||||||
{std::get<1>(item).first, std::get<1>(item).second, ext_f};
|
mapnik::util::index_record rec = {std::get<1>(item).first, std::get<1>(item).second, ext_f};
|
||||||
tree.insert(rec, 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);
|
std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
std::clog << "cannot open index file for writing file \""
|
std::clog << "cannot open index file for writing file \"" << (filename + ".index") << "\"" << std::endl;
|
||||||
<< (filename + ".index") << "\"" << std::endl;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -36,10 +36,12 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template <typename T>
|
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)
|
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;
|
using box_type = typename T::value_type::first_type;
|
||||||
csv_utils::csv_file_parser p;
|
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.separator_ = separator;
|
||||||
p.quote_ = quote;
|
p.quote_ = quote;
|
||||||
|
|
||||||
|
|
||||||
util::mapped_memory_file csv_file{filename};
|
util::mapped_memory_file csv_file{filename};
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
p.parse_csv_and_boxes(csv_file.file(), boxes);
|
p.parse_csv_and_boxes(csv_file.file(), boxes);
|
||||||
return std::make_pair(true, box_type(p.extent_));
|
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;
|
std::clog << ex.what() << std::endl;
|
||||||
return std::make_pair(false, box_type(p.extent_));
|
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 box_type = mapnik::box2d<float>;
|
||||||
using item_type = std::pair<box_type, std::pair<std::uint64_t, std::uint64_t>>;
|
using item_type = std::pair<box_type, std::pair<std::uint64_t, std::uint64_t>>;
|
||||||
using boxes_type = std::vector<item_type>;
|
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
|
||||||
|
|
|
@ -26,11 +26,17 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <mapnik/geometry/box2d.hpp>
|
#include <mapnik/geometry/box2d.hpp>
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template <typename T>
|
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);
|
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
|
#endif // MAPNIK_UTILS_PROCESS_CSV_FILE_HPP
|
||||||
|
|
|
@ -43,8 +43,7 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr mapnik::json::well_known_names feature_properties[] = {
|
constexpr mapnik::json::well_known_names feature_properties[] = {mapnik::json::well_known_names::type,
|
||||||
mapnik::json::well_known_names::type,
|
|
||||||
mapnik::json::well_known_names::geometry,
|
mapnik::json::well_known_names::geometry,
|
||||||
mapnik::json::well_known_names::properties}; // sorted
|
mapnik::json::well_known_names::properties}; // sorted
|
||||||
|
|
||||||
|
@ -56,22 +55,22 @@ constexpr mapnik::json::well_known_names geometry_collection_properties[] = {
|
||||||
mapnik::json::well_known_names::type,
|
mapnik::json::well_known_names::type,
|
||||||
mapnik::json::well_known_names::geometries}; // sorted
|
mapnik::json::well_known_names::geometries}; // sorted
|
||||||
|
|
||||||
|
template<typename Keys>
|
||||||
template <typename Keys>
|
|
||||||
std::string join(Keys const& keys)
|
std::string join(Keys const& keys)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto const& key : keys)
|
for (auto const& key : keys)
|
||||||
{
|
{
|
||||||
if (!first) result += ",";
|
if (!first)
|
||||||
|
result += ",";
|
||||||
result += "\"" + std::string(mapnik::json::wkn_to_string(key)) + "\"";
|
result += "\"" + std::string(mapnik::json::wkn_to_string(key)) + "\"";
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator, typename Keys>
|
template<typename Iterator, typename Keys>
|
||||||
bool has_keys(Iterator first1, Iterator last1, Keys const& keys)
|
bool has_keys(Iterator first1, Iterator last1, Keys const& keys)
|
||||||
{
|
{
|
||||||
auto first2 = std::begin(keys);
|
auto first2 = std::begin(keys);
|
||||||
|
@ -86,55 +85,57 @@ bool has_keys(Iterator first1, Iterator last1, Keys const& keys)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Keys>
|
template<typename Keys>
|
||||||
bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& keys, bool verbose)
|
bool validate_geojson_feature(mapnik::json::geojson_value& value, Keys const& keys, bool verbose)
|
||||||
{
|
{
|
||||||
if (!value.is<mapnik::json::geojson_object>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
mapnik::json::geojson_object & feature = mapnik::util::get<mapnik::json::geojson_object>(value);
|
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)
|
std::sort(feature.begin(), feature.end(), [](auto const& e0, auto const& e1) {
|
||||||
{
|
|
||||||
return std::get<0>(e0) < std::get<0>(e1);
|
return std::get<0>(e0) < std::get<0>(e1);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!has_keys(feature.begin(), feature.end(), feature_properties))
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto & elem : feature)
|
for (auto& elem : feature)
|
||||||
{
|
{
|
||||||
auto const key = std::get<0>(elem);
|
auto const key = std::get<0>(elem);
|
||||||
if (key == mapnik::json::well_known_names::geometry)
|
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 (!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;
|
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
|
// sort by property name
|
||||||
std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1)
|
std::sort(geometry.begin(), geometry.end(), [](auto const& e0, auto const& e1) {
|
||||||
{
|
|
||||||
return std::get<0>(e0) < std::get<0>(e1);
|
return std::get<0>(e0) < std::get<0>(e1);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!has_keys(geometry.begin(), geometry.end(), geometry_properties)
|
if (!has_keys(geometry.begin(), geometry.end(), geometry_properties) &&
|
||||||
&& !has_keys(geometry.begin(), geometry.end(), geometry_collection_properties))
|
!has_keys(geometry.begin(), geometry.end(), geometry_collection_properties))
|
||||||
{
|
{
|
||||||
if (verbose) std::clog << "\"geometry\": xxx <-- expecting one of " << join(geometry_properties)
|
if (verbose)
|
||||||
<< " or " << join(geometry_collection_properties) << std::endl;
|
std::clog << "\"geometry\": xxx <-- expecting one of " << join(geometry_properties) << " or "
|
||||||
|
<< join(geometry_collection_properties) << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::geometry::geometry_types geom_type;
|
mapnik::geometry::geometry_types geom_type;
|
||||||
mapnik::json::positions const* coordinates = nullptr;
|
mapnik::json::positions const* coordinates = nullptr;
|
||||||
for (auto & elem2 : geometry)
|
for (auto& elem2 : geometry)
|
||||||
{
|
{
|
||||||
auto const key2 = std::get<0>(elem2);
|
auto const key2 = std::get<0>(elem2);
|
||||||
if (key2 == mapnik::json::well_known_names::type)
|
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);
|
auto const& geom_type_value = std::get<1>(elem2);
|
||||||
if (!geom_type_value.is<mapnik::geometry::geometry_types>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
geom_type = mapnik::util::get<mapnik::geometry::geometry_types>(geom_type_value);
|
geom_type = mapnik::util::get<mapnik::geometry::geometry_types>(geom_type_value);
|
||||||
if (geom_type == mapnik::geometry::geometry_types::GeometryCollection)
|
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;
|
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);
|
auto const& coordinates_value = std::get<1>(elem2);
|
||||||
if (!coordinates_value.is<mapnik::json::positions>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
coordinates = &mapnik::util::get<mapnik::json::positions>(coordinates_value);
|
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
|
// expecting single position
|
||||||
if (!coordinates->is<mapnik::json::point>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +183,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
|
||||||
// expecting
|
// expecting
|
||||||
if (!coordinates->is<mapnik::json::ring>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
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);
|
auto const& ring = mapnik::util::get<mapnik::json::ring>(*coordinates);
|
||||||
if (ring.size() < 2)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +203,8 @@ bool validate_geojson_feature(mapnik::json::geojson_value & value, Keys const& k
|
||||||
// expecting
|
// expecting
|
||||||
if (!coordinates->is<mapnik::json::rings>())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
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);
|
auto const& rings = mapnik::util::get<mapnik::json::rings>(*coordinates);
|
||||||
if (rings.size() < 1)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
for (auto const& ring : rings)
|
for (auto const& ring : rings)
|
||||||
{
|
{
|
||||||
if (ring.size() < 4)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,20 +238,20 @@ using base_iterator_type = char const*;
|
||||||
|
|
||||||
auto const& geojson_value = mapnik::json::grammar::geojson_value;
|
auto const& geojson_value = mapnik::json::grammar::geojson_value;
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
template <typename T>
|
std::pair<bool, typename T::value_type::first_type>
|
||||||
std::pair<bool,typename T::value_type::first_type> process_geojson_file_x3(T & boxes, std::string const& filename, bool validate_features, bool verbose)
|
process_geojson_file_x3(T& boxes, std::string const& filename, bool validate_features, bool verbose)
|
||||||
{
|
{
|
||||||
using box_type = typename T::value_type::first_type;
|
using box_type = typename T::value_type::first_type;
|
||||||
box_type extent;
|
box_type extent;
|
||||||
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
||||||
mapnik::mapped_region_ptr mapped_region;
|
mapnik::mapped_region_ptr mapped_region;
|
||||||
boost::optional<mapnik::mapped_region_ptr> memory =
|
boost::optional<mapnik::mapped_region_ptr> memory = mapnik::mapped_memory_cache::instance().find(filename, true);
|
||||||
mapnik::mapped_memory_cache::instance().find(filename, true);
|
|
||||||
if (!memory)
|
if (!memory)
|
||||||
{
|
{
|
||||||
std::clog << "Error : cannot memory map " << filename << std::endl;
|
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
|
try
|
||||||
{
|
{
|
||||||
mapnik::json::extract_bounding_boxes(itr, end, boxes);
|
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 << ex.what() << std::endl;
|
||||||
std::clog << "Expected: " << ex.which();
|
std::clog << "Expected: " << ex.which();
|
||||||
std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << '"' << std::endl;
|
std::clog << " Got: \"" << std::string(ex.where(), ex.where() + 200) << '"' << std::endl;
|
||||||
return std::make_pair(false, extent);
|
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);
|
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;
|
using space_type = mapnik::json::grammar::space_type;
|
||||||
auto keys = mapnik::json::get_keys();
|
auto keys = mapnik::json::get_keys();
|
||||||
#if BOOST_VERSION >= 106700
|
#if BOOST_VERSION >= 106700
|
||||||
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(keys)
|
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(keys)[geojson_value];
|
||||||
[ geojson_value ];
|
|
||||||
#else
|
#else
|
||||||
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(std::ref(keys))
|
auto feature_grammar = x3::with<mapnik::json::grammar::keys_tag>(std::ref(keys))[geojson_value];
|
||||||
[ geojson_value ];
|
|
||||||
#endif
|
#endif
|
||||||
for (auto const& item : boxes)
|
for (auto const& item : boxes)
|
||||||
{
|
{
|
||||||
if (item.first.valid())
|
if (item.first.valid())
|
||||||
{
|
{
|
||||||
if (!extent.valid()) extent = item.first;
|
if (!extent.valid())
|
||||||
else extent.expand_to_include(item.first);
|
extent = item.first;
|
||||||
|
else
|
||||||
|
extent.expand_to_include(item.first);
|
||||||
if (validate_features)
|
if (validate_features)
|
||||||
{
|
{
|
||||||
base_iterator_type feat_itr = start + item.second.first;
|
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);
|
bool result = x3::phrase_parse(feat_itr, feat_end, feature_grammar, space_type(), feature_value);
|
||||||
if (!result || feat_itr != feat_end)
|
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);
|
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);
|
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);
|
return std::make_pair(false, extent);
|
||||||
}
|
}
|
||||||
if (!validate_geojson_feature(feature_value, keys, verbose))
|
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);
|
return std::make_pair(false, extent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (validate_features)
|
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(false, extent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::make_pair(true, 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
|
||||||
|
|
|
@ -26,11 +26,14 @@
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
template <typename T>
|
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);
|
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
|
#endif // MAPNIK_UTILS_PROCESS_GEOJSON_FILE_X3_HPP
|
||||||
|
|
|
@ -17,7 +17,7 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
int main (int argc,char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ int main (int argc,char** argv)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::options_description desc("mapnik-render utility");
|
po::options_description desc("mapnik-render utility");
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce usage message")
|
("help,h", "produce usage message")
|
||||||
("version,V","print version string")
|
("version,V","print version string")
|
||||||
|
@ -48,17 +49,17 @@ int main (int argc,char** argv)
|
||||||
("map-height",po::value<int>(),"map height in pixels")
|
("map-height",po::value<int>(),"map height in pixels")
|
||||||
("variables","make map parameters available as render-time variables")
|
("variables","make map parameters available as render-time variables")
|
||||||
;
|
;
|
||||||
|
// clang-format on
|
||||||
po::positional_options_description p;
|
po::positional_options_description p;
|
||||||
p.add("xml",1);
|
p.add("xml", 1);
|
||||||
p.add("img",1);
|
p.add("img", 1);
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
|
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
if (vm.count("version"))
|
if (vm.count("version"))
|
||||||
{
|
{
|
||||||
std::clog <<"version " << MAPNIK_VERSION_STRING << std::endl;
|
std::clog << "version " << MAPNIK_VERSION_STRING << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +81,7 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
if (vm.count("xml"))
|
if (vm.count("xml"))
|
||||||
{
|
{
|
||||||
xml_file=vm["xml"].as<std::string>();
|
xml_file = vm["xml"].as<std::string>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -90,7 +91,7 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
if (vm.count("img"))
|
if (vm.count("img"))
|
||||||
{
|
{
|
||||||
img_file=vm["img"].as<std::string>();
|
img_file = vm["img"].as<std::string>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -100,7 +101,7 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
if (vm.count("scale-factor"))
|
if (vm.count("scale-factor"))
|
||||||
{
|
{
|
||||||
scale_factor=vm["scale-factor"].as<double>();
|
scale_factor = vm["scale-factor"].as<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("variables"))
|
if (vm.count("variables"))
|
||||||
|
@ -108,21 +109,23 @@ int main (int argc,char** argv)
|
||||||
params_as_variables = true;
|
params_as_variables = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("map-width")) {
|
if (vm.count("map-width"))
|
||||||
|
{
|
||||||
map_width = vm["map-width"].as<int>();
|
map_width = vm["map-width"].as<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vm.count("map-height")) {
|
if (vm.count("map-height"))
|
||||||
|
{
|
||||||
map_height = vm["map-height"].as<int>();
|
map_height = vm["map-height"].as<int>();
|
||||||
}
|
}
|
||||||
|
|
||||||
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
mapnik::datasource_cache::instance().register_datasources("./plugins/input/");
|
||||||
mapnik::freetype_engine::register_fonts("./fonts",true);
|
mapnik::freetype_engine::register_fonts("./fonts", true);
|
||||||
mapnik::Map map(map_width,map_height);
|
mapnik::Map map(map_width, map_height);
|
||||||
mapnik::load_map(map,xml_file,true);
|
mapnik::load_map(map, xml_file, true);
|
||||||
map.zoom_all();
|
map.zoom_all();
|
||||||
mapnik::image_rgba8 im(map.width(),map.height());
|
mapnik::image_rgba8 im(map.width(), map.height());
|
||||||
mapnik::request req(map.width(),map.height(),map.get_current_extent());
|
mapnik::request req(map.width(), map.height(), map.get_current_extent());
|
||||||
req.set_buffer_size(map.buffer_size());
|
req.set_buffer_size(map.buffer_size());
|
||||||
mapnik::attributes vars;
|
mapnik::attributes vars;
|
||||||
if (params_as_variables)
|
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();
|
ren.apply();
|
||||||
mapnik::save_to_file(im,img_file);
|
mapnik::save_to_file(im, img_file);
|
||||||
if (auto_open)
|
if (auto_open)
|
||||||
{
|
{
|
||||||
std::ostringstream s;
|
std::ostringstream s;
|
||||||
|
@ -170,8 +173,7 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << "rendered to: " << img_file << "\n";
|
std::clog << "rendered to: " << img_file << "\n";
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception const& ex)
|
||||||
catch (std::exception const& ex)
|
|
||||||
{
|
{
|
||||||
std::clog << "Error " << ex.what() << std::endl;
|
std::clog << "Error " << ex.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -45,25 +44,26 @@ using mapnik::datasource_exception;
|
||||||
|
|
||||||
const int MAXDEPTH = 64;
|
const int MAXDEPTH = 64;
|
||||||
const int DEFAULT_DEPTH = 8;
|
const int DEFAULT_DEPTH = 8;
|
||||||
const double MINRATIO=0.5;
|
const double MINRATIO = 0.5;
|
||||||
const double MAXRATIO=0.8;
|
const double MAXRATIO = 0.8;
|
||||||
const double DEFAULT_RATIO=0.55;
|
const double DEFAULT_RATIO = 0.55;
|
||||||
|
|
||||||
int main (int argc,char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
using namespace mapnik;
|
using namespace mapnik;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
bool verbose=false;
|
bool verbose = false;
|
||||||
unsigned int depth=DEFAULT_DEPTH;
|
unsigned int depth = DEFAULT_DEPTH;
|
||||||
double ratio=DEFAULT_RATIO;
|
double ratio = DEFAULT_RATIO;
|
||||||
vector<string> ogr_files;
|
vector<string> ogr_files;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::options_description desc("ogrindex utility");
|
po::options_description desc("ogrindex utility");
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce usage message")
|
("help,h", "produce usage message")
|
||||||
("version,V", "print version string")
|
("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)")
|
("ratio,r", po::value<double>(), "split ratio (default 0.55)")
|
||||||
("ogr_files", po::value<vector<string> >(), "ogr supported files to index: file1 file2 ...fileN")
|
("ogr_files", po::value<vector<string> >(), "ogr supported files to index: file1 file2 ...fileN")
|
||||||
;
|
;
|
||||||
|
// clang-format on
|
||||||
po::positional_options_description p;
|
po::positional_options_description p;
|
||||||
p.add("ogr_files",-1);
|
p.add("ogr_files", -1);
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
|
po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
if (vm.count("version"))
|
if (vm.count("version"))
|
||||||
{
|
{
|
||||||
std::clog<<"version 0.1.0" <<std::endl;
|
std::clog << "version 0.1.0" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (vm.count("help"))
|
if (vm.count("help"))
|
||||||
|
@ -99,10 +99,9 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
if (vm.count("ogr_files"))
|
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;
|
std::clog << "Exception of unknown type!" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -121,9 +120,9 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << "processing " << *itr << std::endl;
|
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;
|
std::clog << "error : file " << ogrname << " doesn't exists" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
|
@ -131,11 +130,12 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
// TODO - layer names don't match dataset name, so this will break for
|
// TODO - layer names don't match dataset name, so this will break for
|
||||||
// any layer types of ogr than shapefiles, etc
|
// any layer types of ogr than shapefiles, etc
|
||||||
size_t breakpoint = ogrname.find_last_of (".");
|
size_t breakpoint = ogrname.find_last_of(".");
|
||||||
if (breakpoint == string::npos) breakpoint = ogrname.length();
|
if (breakpoint == string::npos)
|
||||||
std::string ogrlayername (ogrname.substr(0, breakpoint));
|
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;
|
std::clog << "error : " << ogrlayername << ".ogrindex file already exists for " << ogrname << std::endl;
|
||||||
continue;
|
continue;
|
||||||
|
@ -144,24 +144,23 @@ int main (int argc,char** argv)
|
||||||
mapnik::parameters params;
|
mapnik::parameters params;
|
||||||
params["type"] = "ogr";
|
params["type"] = "ogr";
|
||||||
params["file"] = ogrname;
|
params["file"] = ogrname;
|
||||||
//unsigned first = 0;
|
// unsigned first = 0;
|
||||||
params["layer_by_index"] = 0;//ogrlayername;
|
params["layer_by_index"] = 0; // ogrlayername;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ogr_datasource ogr (params);
|
ogr_datasource ogr(params);
|
||||||
|
|
||||||
|
|
||||||
box2d<double> extent = ogr.envelope();
|
box2d<double> extent = ogr.envelope();
|
||||||
quadtree<int> tree (extent, depth, ratio);
|
quadtree<int> tree(extent, depth, ratio);
|
||||||
int count=0;
|
int count = 0;
|
||||||
|
|
||||||
std::clog << "file:" << ogrname << std::endl;
|
std::clog << "file:" << ogrname << std::endl;
|
||||||
std::clog << "layer:" << ogrlayername << std::endl;
|
std::clog << "layer:" << ogrlayername << std::endl;
|
||||||
std::clog << "extent:" << extent << std::endl;
|
std::clog << "extent:" << extent << std::endl;
|
||||||
|
|
||||||
mapnik::query q (extent, 1.0);
|
mapnik::query q(extent, 1.0);
|
||||||
mapnik::featureset_ptr itr = ogr.features (q);
|
mapnik::featureset_ptr itr = ogr.features(q);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
@ -173,8 +172,9 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
box2d<double> item_ext = fp->envelope();
|
box2d<double> item_ext = fp->envelope();
|
||||||
|
|
||||||
tree.insert (count, item_ext);
|
tree.insert(count, item_ext);
|
||||||
if (verbose) {
|
if (verbose)
|
||||||
|
{
|
||||||
std::clog << "record number " << (count + 1) << " box=" << item_ext << std::endl;
|
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::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);
|
std::ios::in | std::ios::out | std::ios::trunc | std::ios::binary);
|
||||||
if (!file) {
|
if (!file)
|
||||||
std::clog << "cannot open ogrindex file for writing file \""
|
{
|
||||||
<< (ogrlayername+".ogrindex") << "\"" << std::endl;
|
std::clog << "cannot open ogrindex file for writing file \"" << (ogrlayername + ".ogrindex") << "\""
|
||||||
} else {
|
<< std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tree.trim();
|
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);
|
file.exceptions(std::ios::failbit | std::ios::badbit);
|
||||||
tree.write(file);
|
tree.write(file);
|
||||||
file.flush();
|
file.flush();
|
||||||
|
@ -198,7 +201,7 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// catch problem at the datasource creation
|
// catch problem at the datasource creation
|
||||||
catch (const mapnik::datasource_exception & ex )
|
catch (const mapnik::datasource_exception& ex)
|
||||||
{
|
{
|
||||||
std::clog << ex.what() << "\n";
|
std::clog << ex.what() << "\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -206,10 +209,10 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
std::clog << "unknown exception..." << "\n";
|
std::clog << "unknown exception..."
|
||||||
|
<< "\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::clog << "done!" << std::endl;
|
std::clog << "done!" << std::endl;
|
||||||
|
|
|
@ -35,20 +35,20 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
//stl
|
// stl
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
|
||||||
int main ( int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
po::options_description desc("Postgresql/PostGIS to SQLite3 converter\n 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
|
try
|
||||||
{
|
{
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,?","Display this help screen.")
|
("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.")
|
("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.")
|
("file,f",po::value<std::string>(),"Use this option to specify the name of the file to create.")
|
||||||
|
|
||||||
;
|
;
|
||||||
|
// clang-format on
|
||||||
//po::positional_options_description p;
|
// po::positional_options_description p;
|
||||||
//p.add("table",1);
|
// p.add("table",1);
|
||||||
|
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
//positional(p)
|
// positional(p)
|
||||||
po::store(po::command_line_parser(argc,argv).options(desc).run(),vm);
|
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
if (vm.count("help"))
|
if (vm.count("help"))
|
||||||
|
@ -76,7 +76,7 @@ int main ( int argc, char** argv)
|
||||||
std::cout << usage << "\n";
|
std::cout << usage << "\n";
|
||||||
return EXIT_SUCCESS;
|
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 << desc << "\n";
|
||||||
std::cout << usage << "\n";
|
std::cout << usage << "\n";
|
||||||
|
@ -98,20 +98,20 @@ int main ( int argc, char** argv)
|
||||||
std::shared_ptr<Connection> conn(creator());
|
std::shared_ptr<Connection> conn(creator());
|
||||||
|
|
||||||
std::string query = vm["query"].as<std::string>();
|
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::string output_file = vm["file"].as<std::string>();
|
||||||
|
|
||||||
std::cout << "output_table : " << output_table_name << "\n";
|
std::cout << "output_table : " << output_table_name << "\n";
|
||||||
|
|
||||||
mapnik::pgsql2sqlite(conn,query,output_table_name,output_file);
|
mapnik::pgsql2sqlite(conn, query, output_table_name, output_file);
|
||||||
}
|
} catch (mapnik::datasource_exception& ex)
|
||||||
catch (mapnik::datasource_exception & ex)
|
|
||||||
{
|
{
|
||||||
std::cerr << ex.what() << "\n";
|
std::cerr << ex.what() << "\n";
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
} catch (std::exception& e)
|
||||||
catch(std::exception& e) {
|
{
|
||||||
std::cerr << desc << "\n";
|
std::cerr << desc << "\n";
|
||||||
std::cout << usage << "\n";
|
std::cout << usage << "\n";
|
||||||
std::cerr << e.what() << "\n";
|
std::cerr << e.what() << "\n";
|
||||||
|
|
|
@ -41,7 +41,7 @@ MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
//st
|
// st
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
@ -50,21 +50,22 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
static std::string numeric2string(const char* buf)
|
static std::string numeric2string(const char* buf)
|
||||||
{
|
{
|
||||||
std::int16_t ndigits = int2net(buf);
|
std::int16_t ndigits = int2net(buf);
|
||||||
std::int16_t weight = int2net(buf+2);
|
std::int16_t weight = int2net(buf + 2);
|
||||||
std::int16_t sign = int2net(buf+4);
|
std::int16_t sign = int2net(buf + 4);
|
||||||
std::int16_t dscale = int2net(buf+6);
|
std::int16_t dscale = int2net(buf + 6);
|
||||||
|
|
||||||
const std::unique_ptr<std::int16_t[]> digits(new std::int16_t[ndigits]);
|
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;
|
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;
|
int d = 0;
|
||||||
|
|
||||||
// Each numeric "digit" is actually a value between 0000 and 9999 stored in a 16 bit field.
|
// 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.
|
// 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.
|
// 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)
|
if (i <= weight && d < ndigits)
|
||||||
{
|
{
|
||||||
|
@ -94,7 +95,7 @@ static std::string numeric2string(const char* buf)
|
||||||
ss << "0"; // 0100 - 0999;
|
ss << "0"; // 0100 - 0999;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
switch(digits[d])
|
switch (digits[d])
|
||||||
{
|
{
|
||||||
case 0 ... 9:
|
case 0 ... 9:
|
||||||
ss << "000"; // 0000 - 0009
|
ss << "000"; // 0000 - 0009
|
||||||
|
@ -133,22 +134,26 @@ static std::string numeric2string(const char* buf)
|
||||||
value = 0;
|
value = 0;
|
||||||
|
|
||||||
// Output up to 4 decimal digits for this value
|
// Output up to 4 decimal digits for this value
|
||||||
if (dscale > 0) {
|
if (dscale > 0)
|
||||||
|
{
|
||||||
ss << (value / 1000);
|
ss << (value / 1000);
|
||||||
value %= 1000;
|
value %= 1000;
|
||||||
dscale--;
|
dscale--;
|
||||||
}
|
}
|
||||||
if (dscale > 0) {
|
if (dscale > 0)
|
||||||
|
{
|
||||||
ss << (value / 100);
|
ss << (value / 100);
|
||||||
value %= 100;
|
value %= 100;
|
||||||
dscale--;
|
dscale--;
|
||||||
}
|
}
|
||||||
if (dscale > 0) {
|
if (dscale > 0)
|
||||||
|
{
|
||||||
ss << (value / 10);
|
ss << (value / 10);
|
||||||
value %= 10;
|
value %= 10;
|
||||||
dscale--;
|
dscale--;
|
||||||
}
|
}
|
||||||
if (dscale > 0) {
|
if (dscale > 0)
|
||||||
|
{
|
||||||
ss << value;
|
ss << value;
|
||||||
dscale--;
|
dscale--;
|
||||||
}
|
}
|
||||||
|
@ -159,10 +164,9 @@ static std::string numeric2string(const char* buf)
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
template <typename Connection>
|
template<typename Connection>
|
||||||
void pgsql2sqlite(Connection conn,
|
void pgsql2sqlite(Connection conn,
|
||||||
std::string const& query,
|
std::string const& query,
|
||||||
std::string const& output_table_name,
|
std::string const& output_table_name,
|
||||||
|
@ -178,9 +182,10 @@ void pgsql2sqlite(Connection conn,
|
||||||
|
|
||||||
select_sql << "select ";
|
select_sql << "select ";
|
||||||
|
|
||||||
for (int i=0; i<count; ++i)
|
for (int i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
if (i!=0) select_sql << ",";
|
if (i != 0)
|
||||||
|
select_sql << ",";
|
||||||
select_sql << "\"" << rs->getFieldName(i) << "\"";
|
select_sql << "\"" << rs->getFieldName(i) << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,16 +193,16 @@ void pgsql2sqlite(Connection conn,
|
||||||
|
|
||||||
std::string table_name = mapnik::sql_utils::table_from_sql(query);
|
std::string table_name = mapnik::sql_utils::table_from_sql(query);
|
||||||
|
|
||||||
std::string schema_name="";
|
std::string schema_name = "";
|
||||||
std::string::size_type idx=table_name.find_last_of('.');
|
std::string::size_type idx = table_name.find_last_of('.');
|
||||||
if (idx!=std::string::npos)
|
if (idx != std::string::npos)
|
||||||
{
|
{
|
||||||
schema_name=table_name.substr(0,idx);
|
schema_name = table_name.substr(0, idx);
|
||||||
table_name=table_name.substr(idx+1);
|
table_name = table_name.substr(idx + 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
table_name=table_name.substr(0);
|
table_name = table_name.substr(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostringstream geom_col_sql;
|
std::ostringstream geom_col_sql;
|
||||||
|
@ -205,7 +210,7 @@ void pgsql2sqlite(Connection conn,
|
||||||
geom_col_sql << "where f_table_name='" << table_name << "'";
|
geom_col_sql << "where f_table_name='" << table_name << "'";
|
||||||
if (schema_name.length() > 0)
|
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());
|
rs = conn->executeQuery(geom_col_sql.str());
|
||||||
|
@ -214,9 +219,9 @@ void pgsql2sqlite(Connection conn,
|
||||||
std::string geom_col = "UNKNOWN";
|
std::string geom_col = "UNKNOWN";
|
||||||
std::string geom_type = "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";
|
std::clog << "could not convert srid to integer\n";
|
||||||
}
|
}
|
||||||
|
@ -226,7 +231,9 @@ void pgsql2sqlite(Connection conn,
|
||||||
|
|
||||||
// add AsBinary(<geometry_column>) modifier
|
// add AsBinary(<geometry_column>) modifier
|
||||||
std::string select_sql_str = select_sql.str();
|
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
|
#ifdef MAPNIK_DEBUG
|
||||||
std::cout << select_sql_str << "\n";
|
std::cout << select_sql_str << "\n";
|
||||||
|
@ -235,19 +242,22 @@ void pgsql2sqlite(Connection conn,
|
||||||
std::ostringstream cursor_sql;
|
std::ostringstream cursor_sql;
|
||||||
std::string cursor_name("my_cursor");
|
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());
|
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();
|
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;
|
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;
|
int geometry_oid = -1;
|
||||||
|
|
||||||
|
@ -255,7 +265,7 @@ void pgsql2sqlite(Connection conn,
|
||||||
|
|
||||||
context_ptr ctx = std::make_shared<context_type>();
|
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);
|
const char* field_name = cursor->getFieldName(pos);
|
||||||
ctx->push(field_name);
|
ctx->push(field_name);
|
||||||
|
@ -264,7 +274,7 @@ void pgsql2sqlite(Connection conn,
|
||||||
{
|
{
|
||||||
create_sql << ",";
|
create_sql << ",";
|
||||||
}
|
}
|
||||||
output_table_insert_sql +=",?";
|
output_table_insert_sql += ",?";
|
||||||
int oid = cursor->getTypeOID(pos);
|
int oid = cursor->getTypeOID(pos);
|
||||||
if (geom_col == cursor->getFieldName(pos))
|
if (geom_col == cursor->getFieldName(pos))
|
||||||
{
|
{
|
||||||
|
@ -289,41 +299,39 @@ void pgsql2sqlite(Connection conn,
|
||||||
create_sql << "' TEXT";
|
create_sql << "' TEXT";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
create_sql << ");";
|
create_sql << ");";
|
||||||
output_table_insert_sql +=")";
|
output_table_insert_sql += ")";
|
||||||
|
|
||||||
std::cout << "client_encoding=" << conn->client_encoding() << "\n";
|
std::cout << "client_encoding=" << conn->client_encoding() << "\n";
|
||||||
std::cout << "geometry_column=" << geom_col << "(" << geom_type
|
std::cout << "geometry_column=" << geom_col << "(" << geom_type << ") srid=" << srid << " oid=" << geometry_oid
|
||||||
<< ") srid=" << srid << " oid=" << geometry_oid << "\n";
|
<< "\n";
|
||||||
|
|
||||||
|
|
||||||
db.execute("begin;");
|
db.execute("begin;");
|
||||||
// output table sql
|
// output table sql
|
||||||
db.execute(create_sql.str());
|
db.execute(create_sql.str());
|
||||||
|
|
||||||
// spatial index sql
|
// spatial index sql
|
||||||
std::string spatial_index_sql = "create virtual table idx_" + output_table_name
|
std::string spatial_index_sql =
|
||||||
+ "_" + geom_col + " using rtree(pkid, xmin, xmax, ymin, ymax)";
|
"create virtual table idx_" + output_table_name + "_" + geom_col + " using rtree(pkid, xmin, xmax, ymin, ymax)";
|
||||||
|
|
||||||
db.execute(spatial_index_sql);
|
db.execute(spatial_index_sql);
|
||||||
|
|
||||||
//blob_to_hex hex;
|
// blob_to_hex hex;
|
||||||
int pkid = 0;
|
int pkid = 0;
|
||||||
|
|
||||||
std::string spatial_index_insert_sql = "insert into idx_" + output_table_name + "_"
|
std::string spatial_index_insert_sql =
|
||||||
+ geom_col + " values (?,?,?,?,?)" ;
|
"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
|
#ifdef MAPNIK_DEBUG
|
||||||
std::cout << output_table_insert_sql << "\n";
|
std::cout << output_table_insert_sql << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sqlite::prepared_statement output_table(db,output_table_insert_sql);
|
sqlite::prepared_statement output_table(db, output_table_insert_sql);
|
||||||
|
|
||||||
while (cursor->next())
|
while (cursor->next())
|
||||||
{
|
{
|
||||||
|
@ -332,23 +340,22 @@ void pgsql2sqlite(Connection conn,
|
||||||
sqlite::record_type output_rec;
|
sqlite::record_type output_rec;
|
||||||
output_rec.push_back(sqlite::value_type(pkid));
|
output_rec.push_back(sqlite::value_type(pkid));
|
||||||
bool empty_geom = true;
|
bool empty_geom = true;
|
||||||
const char * buf = 0;
|
const char* buf = 0;
|
||||||
for (unsigned pos=0 ; pos < num_fields; ++pos)
|
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);
|
int oid = cursor->getTypeOID(pos);
|
||||||
buf=cursor->getValue(pos);
|
buf = cursor->getValue(pos);
|
||||||
|
|
||||||
switch (oid)
|
switch (oid)
|
||||||
{
|
{
|
||||||
case 25:
|
case 25:
|
||||||
case 1042:
|
case 1042:
|
||||||
case 1043:
|
case 1043: {
|
||||||
{
|
|
||||||
std::string text(buf);
|
std::string text(buf);
|
||||||
boost::algorithm::replace_all(text,"'","''");
|
boost::algorithm::replace_all(text, "'", "''");
|
||||||
output_rec.push_back(sqlite::value_type(text));
|
output_rec.push_back(sqlite::value_type(text));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -358,36 +365,32 @@ void pgsql2sqlite(Connection conn,
|
||||||
case 21:
|
case 21:
|
||||||
output_rec.emplace_back(int(int2net(buf)));
|
output_rec.emplace_back(int(int2net(buf)));
|
||||||
break;
|
break;
|
||||||
case 700:
|
case 700: {
|
||||||
{
|
|
||||||
float val;
|
float val;
|
||||||
float4net(val,buf);
|
float4net(val, buf);
|
||||||
output_rec.emplace_back(double(val));
|
output_rec.emplace_back(double(val));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 701:
|
case 701: {
|
||||||
{
|
|
||||||
double val;
|
double val;
|
||||||
float8net(val,buf);
|
float8net(val, buf);
|
||||||
output_rec.emplace_back(val);
|
output_rec.emplace_back(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1700:
|
case 1700: {
|
||||||
{
|
|
||||||
std::string str = numeric2string(buf);
|
std::string str = numeric2string(buf);
|
||||||
double val;
|
double val;
|
||||||
if (mapnik::util::string2double(str,val))
|
if (mapnik::util::string2double(str, val))
|
||||||
{
|
{
|
||||||
output_rec.emplace_back(val);
|
output_rec.emplace_back(val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
{
|
|
||||||
if (oid == geometry_oid)
|
if (oid == geometry_oid)
|
||||||
{
|
{
|
||||||
mapnik::feature_impl feat(ctx,pkid);
|
mapnik::feature_impl feat(ctx, pkid);
|
||||||
mapnik::geometry::geometry<double> geom = geometry_utils::from_wkb(buf, size, wkbGeneric);
|
mapnik::geometry::geometry<double> geom = geometry_utils::from_wkb(buf, size, wkbGeneric);
|
||||||
if (!mapnik::geometry::is_empty(geom))
|
if (!mapnik::geometry::is_empty(geom))
|
||||||
{
|
{
|
||||||
|
@ -404,7 +407,7 @@ void pgsql2sqlite(Connection conn,
|
||||||
empty_geom = false;
|
empty_geom = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output_rec.push_back(sqlite::blob(buf,size));
|
output_rec.push_back(sqlite::blob(buf, size));
|
||||||
}
|
}
|
||||||
else
|
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)
|
if (pkid % 1000 == 0)
|
||||||
{
|
{
|
||||||
|
@ -440,4 +444,4 @@ void pgsql2sqlite(Connection conn,
|
||||||
std::cout << "\r vacumming";
|
std::cout << "\r vacumming";
|
||||||
std::cout << "\n Done!" << std::endl;
|
std::cout << "\n Done!" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
} // namespace mapnik
|
||||||
|
|
|
@ -22,11 +22,12 @@
|
||||||
|
|
||||||
#include "sqlite.hpp"
|
#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;
|
sqlite3* db;
|
||||||
int res = sqlite3_open(name.c_str(), &db);
|
int res = sqlite3_open(name.c_str(), &db);
|
||||||
if (res)
|
if (res)
|
||||||
{
|
{
|
||||||
|
@ -34,25 +35,25 @@ namespace mapnik { namespace sqlite {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
db_ = sqlite_db(db,database_closer());
|
db_ = sqlite_db(db, database_closer());
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::cerr << "Open database " << name << "\n";
|
std::cerr << "Open database " << name << "\n";
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
database::~database() {}
|
database::~database() {}
|
||||||
|
|
||||||
bool database::execute(std::string const& sql)
|
bool database::execute(std::string const& sql)
|
||||||
{
|
{
|
||||||
char * err_msg;
|
char* err_msg;
|
||||||
int res = sqlite3_exec(db_.get(),sql.c_str(),0,0,&err_msg);
|
int res = sqlite3_exec(db_.get(), sql.c_str(), 0, 0, &err_msg);
|
||||||
if (res != SQLITE_OK)
|
if (res != SQLITE_OK)
|
||||||
{
|
{
|
||||||
std::cerr << "SQL"<< sql << " ERR:" << err_msg << "\n";
|
std::cerr << "SQL" << sql << " ERR:" << err_msg << "\n";
|
||||||
sqlite3_free(err_msg);
|
sqlite3_free(err_msg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
} // namespace sqlite
|
||||||
|
} // namespace mapnik
|
||||||
|
|
|
@ -31,7 +31,7 @@ MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
//stl
|
// stl
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,15 +40,16 @@ MAPNIK_DISABLE_WARNING_POP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace mapnik { namespace sqlite {
|
namespace mapnik {
|
||||||
|
namespace sqlite {
|
||||||
|
|
||||||
class database : private util::noncopyable
|
class database : private util::noncopyable
|
||||||
{
|
{
|
||||||
friend class prepared_statement;
|
friend class prepared_statement;
|
||||||
|
|
||||||
struct database_closer
|
struct database_closer
|
||||||
{
|
{
|
||||||
void operator () (sqlite3 * db)
|
void operator()(sqlite3* db)
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::cerr << "close database " << db << "\n";
|
std::cerr << "close database " << db << "\n";
|
||||||
|
@ -64,29 +65,34 @@ namespace mapnik { namespace sqlite {
|
||||||
database(std::string const& name);
|
database(std::string const& name);
|
||||||
~database();
|
~database();
|
||||||
bool execute(std::string const& sql);
|
bool execute(std::string const& sql);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct null_type {};
|
struct null_type
|
||||||
struct blob
|
{};
|
||||||
{
|
struct blob
|
||||||
|
{
|
||||||
blob(const char* buf, unsigned size)
|
blob(const char* buf, unsigned size)
|
||||||
: buf_(buf), size_(size) {}
|
: buf_(buf)
|
||||||
|
, size_(size)
|
||||||
|
{}
|
||||||
|
|
||||||
const char * buf_;
|
const char* buf_;
|
||||||
unsigned size_;
|
unsigned size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
using value_type = mapnik::util::variant<int,double,std::string, blob,null_type>;
|
using value_type = mapnik::util::variant<int, double, std::string, blob, null_type>;
|
||||||
using record_type = std::vector<value_type>;
|
using record_type = std::vector<value_type>;
|
||||||
|
|
||||||
class prepared_statement : util::noncopyable
|
class prepared_statement : util::noncopyable
|
||||||
{
|
{
|
||||||
struct binder
|
struct binder
|
||||||
{
|
{
|
||||||
binder(sqlite3_stmt * stmt, unsigned index)
|
binder(sqlite3_stmt* stmt, unsigned index)
|
||||||
: stmt_(stmt), index_(index) {}
|
: stmt_(stmt)
|
||||||
|
, index_(index)
|
||||||
|
{}
|
||||||
|
|
||||||
bool operator() (null_type )
|
bool operator()(null_type)
|
||||||
{
|
{
|
||||||
if (sqlite3_bind_null(stmt_, index_) != SQLITE_OK)
|
if (sqlite3_bind_null(stmt_, index_) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
|
@ -96,9 +102,9 @@ namespace mapnik { namespace sqlite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (int val)
|
bool operator()(int val)
|
||||||
{
|
{
|
||||||
if (sqlite3_bind_int(stmt_, index_ , val ) != SQLITE_OK)
|
if (sqlite3_bind_int(stmt_, index_, val) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
std::cerr << "cannot bind " << val << "\n";
|
std::cerr << "cannot bind " << val << "\n";
|
||||||
return false;
|
return false;
|
||||||
|
@ -106,9 +112,9 @@ namespace mapnik { namespace sqlite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (double val)
|
bool operator()(double val)
|
||||||
{
|
{
|
||||||
if (sqlite3_bind_double(stmt_, index_ , val ) != SQLITE_OK)
|
if (sqlite3_bind_double(stmt_, index_, val) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
std::cerr << "cannot bind " << val << "\n";
|
std::cerr << "cannot bind " << val << "\n";
|
||||||
return false;
|
return false;
|
||||||
|
@ -116,7 +122,7 @@ namespace mapnik { namespace sqlite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (std::string const& val)
|
bool operator()(std::string const& val)
|
||||||
{
|
{
|
||||||
if (sqlite3_bind_text(stmt_, index_, val.c_str(), val.length(), SQLITE_STATIC) != SQLITE_OK)
|
if (sqlite3_bind_text(stmt_, index_, val.c_str(), val.length(), SQLITE_STATIC) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
|
@ -126,7 +132,7 @@ namespace mapnik { namespace sqlite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator() (blob const& val)
|
bool operator()(blob const& val)
|
||||||
{
|
{
|
||||||
if (sqlite3_bind_blob(stmt_, index_, val.buf_, val.size_, SQLITE_STATIC) != SQLITE_OK)
|
if (sqlite3_bind_blob(stmt_, index_, val.buf_, val.size_, SQLITE_STATIC) != SQLITE_OK)
|
||||||
{
|
{
|
||||||
|
@ -136,19 +142,21 @@ namespace mapnik { namespace sqlite {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3_stmt * stmt_;
|
sqlite3_stmt* stmt_;
|
||||||
unsigned index_;
|
unsigned index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
prepared_statement(database & db, std::string const& sql)
|
prepared_statement(database& db, std::string const& sql)
|
||||||
: db_(db.db_.get()), stmt_(0)
|
: db_(db.db_.get())
|
||||||
|
, stmt_(0)
|
||||||
{
|
{
|
||||||
const char * tail;
|
const char* tail;
|
||||||
//char * err_msg;
|
// char * err_msg;
|
||||||
int res = sqlite3_prepare_v2(db_, sql.c_str(),-1, &stmt_,&tail);
|
int res = sqlite3_prepare_v2(db_, sql.c_str(), -1, &stmt_, &tail);
|
||||||
if (res != SQLITE_OK)
|
if (res != SQLITE_OK)
|
||||||
{
|
{
|
||||||
std::cerr << "ERR:"<< res << "\n";
|
std::cerr << "ERR:" << res << "\n";
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,15 +173,15 @@ namespace mapnik { namespace sqlite {
|
||||||
bool insert_record(record_type const& rec) const
|
bool insert_record(record_type const& rec) const
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
assert( unsigned(sqlite3_bind_parameter_count(stmt_)) == rec.size());
|
assert(unsigned(sqlite3_bind_parameter_count(stmt_)) == rec.size());
|
||||||
#endif
|
#endif
|
||||||
record_type::const_iterator itr = rec.begin();
|
record_type::const_iterator itr = rec.begin();
|
||||||
record_type::const_iterator end = rec.end();
|
record_type::const_iterator end = rec.end();
|
||||||
int count = 1;
|
int count = 1;
|
||||||
for (; itr!=end;++itr)
|
for (; itr != end; ++itr)
|
||||||
{
|
{
|
||||||
binder op(stmt_,count++);
|
binder op(stmt_, count++);
|
||||||
if (!util::apply_visitor(op,*itr))
|
if (!util::apply_visitor(op, *itr))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -186,8 +194,8 @@ namespace mapnik { namespace sqlite {
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sqlite3 * db_;
|
sqlite3* db_;
|
||||||
sqlite3_stmt * stmt_;
|
sqlite3_stmt* stmt_;
|
||||||
};
|
};
|
||||||
}
|
} // namespace sqlite
|
||||||
}
|
} // namespace mapnik
|
||||||
|
|
|
@ -44,15 +44,15 @@ const double DEFAULT_RATIO = 0.55;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define NOMINMAX
|
#define NOMINMAX
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
int main ()
|
int main()
|
||||||
#else
|
#else
|
||||||
int main (int argc,char** argv)
|
int main(int argc, char** argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
using namespace mapnik;
|
using namespace mapnik;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
bool verbose=false;
|
bool verbose = false;
|
||||||
bool index_parts = false;
|
bool index_parts = false;
|
||||||
unsigned int depth = DEFAULT_DEPTH;
|
unsigned int depth = DEFAULT_DEPTH;
|
||||||
double ratio = DEFAULT_RATIO;
|
double ratio = DEFAULT_RATIO;
|
||||||
|
@ -61,6 +61,7 @@ int main (int argc,char** argv)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::options_description desc("shapeindex utility");
|
po::options_description desc("shapeindex utility");
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce usage message")
|
("help,h", "produce usage message")
|
||||||
("version,V","print version string")
|
("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)")
|
("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")
|
("shape_files",po::value<std::vector<std::string> >(),"shape files to index: file1 file2 ...fileN")
|
||||||
;
|
;
|
||||||
|
// clang-format on
|
||||||
po::positional_options_description p;
|
po::positional_options_description p;
|
||||||
p.add("shape_files",-1);
|
p.add("shape_files", -1);
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
const auto wargs = po::split_winmain(GetCommandLineW());
|
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));
|
args.push_back(mapnik::utf16_to_utf8(*it));
|
||||||
po::store(po::command_line_parser(args).options(desc).positional(p).run(), vm);
|
po::store(po::command_line_parser(args).options(desc).positional(p).run(), vm);
|
||||||
#else
|
#else
|
||||||
|
@ -115,10 +116,9 @@ int main (int argc,char** argv)
|
||||||
|
|
||||||
if (vm.count("shape_files"))
|
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;
|
std::clog << "Error: " << ex.what() << std::endl;
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -135,46 +135,45 @@ int main (int argc,char** argv)
|
||||||
for (auto const& filename : shape_files)
|
for (auto const& filename : shape_files)
|
||||||
{
|
{
|
||||||
std::clog << "processing " << filename << std::endl;
|
std::clog << "processing " << filename << std::endl;
|
||||||
std::string shapename (filename);
|
std::string shapename(filename);
|
||||||
boost::algorithm::ireplace_last(shapename,".shp","");
|
boost::algorithm::ireplace_last(shapename, ".shp", "");
|
||||||
std::string shapename_full (shapename + ".shp");
|
std::string shapename_full(shapename + ".shp");
|
||||||
std::string shxname(shapename + ".shx");
|
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;
|
std::clog << "Error : file " << shapename_full << " does not exist" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (! mapnik::util::exists(shxname))
|
if (!mapnik::util::exists(shxname))
|
||||||
{
|
{
|
||||||
std::clog << "Error : shapefile index file (*.shx) " << shxname << " does not exist" << std::endl;
|
std::clog << "Error : shapefile index file (*.shx) " << shxname << " does not exist" << std::endl;
|
||||||
continue;
|
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;
|
std::clog << "Error : cannot open " << shapename_full << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
shape_file shx (shxname);
|
shape_file shx(shxname);
|
||||||
if (!shx.is_open())
|
if (!shx.is_open())
|
||||||
{
|
{
|
||||||
std::clog << "Error : cannot open " << shxname << std::endl;
|
std::clog << "Error : cannot open " << shxname << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int code = shx.read_xdr_integer(); //file_code == 9994
|
int code = shx.read_xdr_integer(); // file_code == 9994
|
||||||
std::clog << code << std::endl;
|
std::clog << code << std::endl;
|
||||||
shx.skip(5*4);
|
shx.skip(5 * 4);
|
||||||
|
|
||||||
int file_length=shx.read_xdr_integer();
|
int file_length = shx.read_xdr_integer();
|
||||||
int version=shx.read_ndr_integer();
|
int version = shx.read_ndr_integer();
|
||||||
int shape_type=shx.read_ndr_integer();
|
int shape_type = shx.read_ndr_integer();
|
||||||
box2d<double> extent;
|
box2d<double> extent;
|
||||||
shx.read_envelope(extent);
|
shx.read_envelope(extent);
|
||||||
|
|
||||||
|
|
||||||
std::clog << "length=" << file_length << std::endl;
|
std::clog << "length=" << file_length << std::endl;
|
||||||
std::clog << "version=" << version << std::endl;
|
std::clog << "version=" << version << std::endl;
|
||||||
std::clog << "type=" << shape_type << std::endl;
|
std::clog << "type=" << shape_type << std::endl;
|
||||||
|
@ -187,12 +186,12 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
int pos = 50;
|
int pos = 50;
|
||||||
shx.seek(pos * 2);
|
shx.seek(pos * 2);
|
||||||
mapnik::box2d<float> extent_f { static_cast<float>(extent.minx()),
|
mapnik::box2d<float> extent_f{static_cast<float>(extent.minx()),
|
||||||
static_cast<float>(extent.miny()),
|
static_cast<float>(extent.miny()),
|
||||||
static_cast<float>(extent.maxx()),
|
static_cast<float>(extent.maxx()),
|
||||||
static_cast<float>(extent.maxy())};
|
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;
|
int count = 0;
|
||||||
|
|
||||||
if (shape_type != shape_io::shape_null)
|
if (shape_type != shape_io::shape_null)
|
||||||
|
@ -216,32 +215,35 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
shape_type = shp.read_ndr_integer();
|
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
|
if (shape_type == shape_io::shape_point || shape_type == shape_io::shape_pointm ||
|
||||||
|| shape_type==shape_io::shape_pointm
|
shape_type == shape_io::shape_pointz)
|
||||||
|| shape_type == shape_io::shape_pointz)
|
|
||||||
{
|
{
|
||||||
double x=shp.read_double();
|
double x = shp.read_double();
|
||||||
double y=shp.read_double();
|
double y = shp.read_double();
|
||||||
item_ext=box2d<double>(x,y,x,y);
|
item_ext = box2d<double>(x, y, x, y);
|
||||||
}
|
}
|
||||||
else if (index_parts &&
|
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_polygon || shape_type == shape_io::shape_polygonm ||
|
||||||
|| shape_type == shape_io::shape_polyline || shape_type == shape_io::shape_polylinem || shape_type == shape_io::shape_polylinez))
|
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);
|
shp.read_envelope(item_ext);
|
||||||
int num_parts = shp.read_ndr_integer();
|
int num_parts = shp.read_ndr_integer();
|
||||||
int num_points = shp.read_ndr_integer();
|
int num_points = shp.read_ndr_integer();
|
||||||
std::vector<int> parts;
|
std::vector<int> parts;
|
||||||
parts.resize(num_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)
|
for (int k = 0; k < num_parts; ++k)
|
||||||
{
|
{
|
||||||
int start = parts[k];
|
int start = parts[k];
|
||||||
int end;
|
int end;
|
||||||
if (k == num_parts - 1) end = num_points;
|
if (k == num_parts - 1)
|
||||||
else end = parts[k + 1];
|
end = num_points;
|
||||||
|
else
|
||||||
|
end = parts[k + 1];
|
||||||
|
|
||||||
mapnik::geometry::linear_ring<double> ring;
|
mapnik::geometry::linear_ring<double> ring;
|
||||||
ring.reserve(end - start);
|
ring.reserve(end - start);
|
||||||
|
@ -258,7 +260,7 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
||||||
}
|
}
|
||||||
mapnik::box2d<float> ext_f {static_cast<float>(item_ext.minx()),
|
mapnik::box2d<float> ext_f{static_cast<float>(item_ext.minx()),
|
||||||
static_cast<float>(item_ext.miny()),
|
static_cast<float>(item_ext.miny()),
|
||||||
static_cast<float>(item_ext.maxx()),
|
static_cast<float>(item_ext.maxx()),
|
||||||
static_cast<float>(item_ext.maxy())};
|
static_cast<float>(item_ext.maxy())};
|
||||||
|
@ -266,7 +268,7 @@ int main (int argc,char** argv)
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
item_ext = mapnik::box2d<double>(); //invalid
|
item_ext = mapnik::box2d<double>(); // invalid
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -279,7 +281,7 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
std::clog << "record number " << record_number << " box=" << item_ext << std::endl;
|
||||||
}
|
}
|
||||||
mapnik::box2d<float> ext_f {static_cast<float>(item_ext.minx()),
|
mapnik::box2d<float> ext_f{static_cast<float>(item_ext.minx()),
|
||||||
static_cast<float>(item_ext.miny()),
|
static_cast<float>(item_ext.miny()),
|
||||||
static_cast<float>(item_ext.maxx()),
|
static_cast<float>(item_ext.maxx()),
|
||||||
static_cast<float>(item_ext.maxy())};
|
static_cast<float>(item_ext.maxy())};
|
||||||
|
@ -294,14 +296,14 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << " number shapes=" << count << std::endl;
|
std::clog << " number shapes=" << count << std::endl;
|
||||||
#ifdef _WIN32
|
#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
|
#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
|
#endif
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
std::clog << "cannot open index file for writing file \""
|
std::clog << "cannot open index file for writing file \"" << (shapename + ".index") << "\""
|
||||||
<< (shapename+".index") << "\"" << std::endl;
|
<< std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,19 +53,16 @@ MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#include "agg_scanline_u.h"
|
#include "agg_scanline_u.h"
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
|
|
||||||
struct main_marker_visitor
|
struct main_marker_visitor
|
||||||
{
|
{
|
||||||
main_marker_visitor(std::string const& svg_name,
|
main_marker_visitor(std::string const& svg_name, double scale_factor, bool verbose, bool auto_open)
|
||||||
double scale_factor,
|
: svg_name_(svg_name)
|
||||||
bool verbose,
|
, scale_factor_(scale_factor)
|
||||||
bool auto_open)
|
, verbose_(verbose)
|
||||||
: svg_name_(svg_name),
|
, auto_open_(auto_open)
|
||||||
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 pixfmt = agg::pixfmt_rgba32_pre;
|
||||||
using renderer_base = agg::renderer_base<pixfmt>;
|
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::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::svg_path_adapter svg_path(stl_storage);
|
||||||
mapnik::svg::renderer_agg<
|
mapnik::svg::
|
||||||
mapnik::svg_path_adapter,
|
renderer_agg<mapnik::svg_path_adapter, mapnik::svg_attribute_type, renderer_solid, agg::pixfmt_rgba32_pre>
|
||||||
mapnik::svg_attribute_type,
|
svg_renderer_this(svg_path, marker.get_data()->attributes());
|
||||||
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);
|
svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);
|
||||||
|
|
||||||
std::string png_name(svg_name_);
|
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);
|
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;
|
int status = 0;
|
||||||
if (auto_open_)
|
if (auto_open_)
|
||||||
{
|
{
|
||||||
|
@ -143,8 +137,8 @@ struct main_marker_visitor
|
||||||
}
|
}
|
||||||
|
|
||||||
// default
|
// default
|
||||||
template <typename T>
|
template<typename T>
|
||||||
int operator() (T const&) const
|
int operator()(T const&) const
|
||||||
{
|
{
|
||||||
std::clog << "svg2png error: failed to process '" << svg_name_ << "'\n";
|
std::clog << "svg2png error: failed to process '" << svg_name_ << "'\n";
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -157,7 +151,7 @@ struct main_marker_visitor
|
||||||
bool auto_open_;
|
bool auto_open_;
|
||||||
};
|
};
|
||||||
|
|
||||||
int main (int argc,char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
|
@ -172,6 +166,7 @@ int main (int argc,char** argv)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
po::options_description desc("svg2png utility");
|
po::options_description desc("svg2png utility");
|
||||||
|
// clang-format off
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "produce usage message")
|
("help,h", "produce usage message")
|
||||||
("version,V","print version string")
|
("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)")
|
("scale-factor", po::value<double>(), "provide scaling factor (default: 1.0)")
|
||||||
("svg",po::value<std::vector<std::string> >(),"svg file to read")
|
("svg",po::value<std::vector<std::string> >(),"svg file to read")
|
||||||
;
|
;
|
||||||
|
// clang-format on
|
||||||
po::positional_options_description p;
|
po::positional_options_description p;
|
||||||
p.add("svg", -1);
|
p.add("svg", -1);
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
|
@ -221,7 +216,7 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
if (vm.count("svg"))
|
if (vm.count("svg"))
|
||||||
{
|
{
|
||||||
svg_files=vm["svg"].as< std::vector<std::string> >();
|
svg_files = vm["svg"].as<std::vector<std::string>>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -237,22 +232,21 @@ int main (int argc,char** argv)
|
||||||
}
|
}
|
||||||
while (itr != svg_files.end())
|
while (itr != svg_files.end())
|
||||||
{
|
{
|
||||||
std::string svg_name (*itr++);
|
std::string svg_name(*itr++);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
std::clog << "found: " << svg_name << "\n";
|
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);
|
main_marker_visitor visitor(svg_name, scale_factor, verbose, auto_open);
|
||||||
status = mapnik::util::apply_visitor(visitor, *marker);
|
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;
|
std::clog << "Exception caught:" << ex.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} catch (...)
|
||||||
catch (...)
|
|
||||||
{
|
{
|
||||||
std::clog << "Exception of unknown type!" << std::endl;
|
std::clog << "Exception of unknown type!" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Reference in a new issue