mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-09 23:24:02 +00:00
128 lines
3.8 KiB
C++
128 lines
3.8 KiB
C++
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
//
|
|
// Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
|
|
//
|
|
// Use, modification and distribution is subject to the Boost Software License,
|
|
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
|
// http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
// Projection example 4, reworked version of example 3
|
|
// Now using svg mapper, multi polygons and specific transform strategy
|
|
|
|
#include <fstream>
|
|
|
|
#include <boost/foreach.hpp>
|
|
#include <boost/geometry.hpp>
|
|
#include <boost/geometry/geometries/point_xy.hpp>
|
|
#include <boost/geometry/geometries/register/point.hpp>
|
|
#include <boost/geometry/geometries/multi_polygon.hpp>
|
|
|
|
#include <boost/geometry/io/svg/svg_mapper.hpp>
|
|
#include <boost/geometry/extensions/gis/latlong/latlong.hpp>
|
|
|
|
#include <boost/geometry/extensions/gis/projections/parameters.hpp>
|
|
#include <boost/geometry/extensions/gis/projections/proj/robin.hpp>
|
|
|
|
// Define a specific projection transformer
|
|
// (NOTE: this might become part of the library)
|
|
template <typename Projection>
|
|
struct projection_transformer
|
|
{
|
|
Projection const& m_prj;
|
|
|
|
inline projection_transformer(Projection const& prj)
|
|
: m_prj(prj)
|
|
{}
|
|
|
|
inline bool apply(typename Projection::geographic_point_type const& p1,
|
|
typename Projection::cartesian_point_type& p2) const
|
|
{
|
|
return m_prj.forward(p1, p2);
|
|
}
|
|
};
|
|
|
|
void read_wkt_and_project_and_map_svg(std::string const& wkt_filename,
|
|
std::string const& svg_filename)
|
|
{
|
|
using namespace boost::geometry;
|
|
|
|
typedef model::ll::point<degree> point_ll_deg;
|
|
typedef model::d2::point_xy<double> point_xy;
|
|
|
|
typedef model::multi_polygon<model::polygon<point_ll_deg> > mp_ll;
|
|
typedef model::multi_polygon<model::polygon<point_xy> > mp_xy;
|
|
|
|
typedef projections::robin_spheroid<point_ll_deg, point_xy> robin;
|
|
|
|
std::vector<mp_ll> countries_in_ll;
|
|
|
|
// Read polygons from WKT
|
|
std::ifstream cpp_file(wkt_filename.c_str());
|
|
if (! cpp_file.is_open())
|
|
{
|
|
throw std::string("File not found: ") + wkt_filename;
|
|
}
|
|
|
|
while (! cpp_file.eof() )
|
|
{
|
|
std::string line;
|
|
std::getline(cpp_file, line);
|
|
if (boost::starts_with(line, "MULTIPOLYGON"))
|
|
{
|
|
countries_in_ll.resize(countries_in_ll.size() + 1);
|
|
boost::geometry::read_wkt(line, countries_in_ll.back());
|
|
}
|
|
}
|
|
|
|
robin prj(projections::init("+ellps=WGS84 +units=m"));
|
|
projection_transformer<robin> projection(prj);
|
|
|
|
// Project the polygons, and at the same time get the bounding box (in xy)
|
|
std::vector<mp_xy> countries_in_xy;
|
|
model::box<point_xy> bbox;
|
|
assign_inverse(bbox);
|
|
BOOST_FOREACH(mp_ll const& country_ll, countries_in_ll)
|
|
{
|
|
mp_xy country_xy;
|
|
if (transform(country_ll, country_xy, projection))
|
|
{
|
|
expand(bbox, return_envelope<model::box<point_xy> >(country_xy));
|
|
countries_in_xy.push_back(country_xy);
|
|
}
|
|
}
|
|
|
|
// Create an SVG image
|
|
std::ofstream svg(svg_filename.c_str());
|
|
boost::geometry::svg_mapper<point_xy> mapper(svg, 1000, 800);
|
|
mapper.add(bbox);
|
|
|
|
BOOST_FOREACH(mp_xy const& country, countries_in_xy)
|
|
{
|
|
mapper.map(country, "fill-opacity:0.6;fill:rgb(153,204,0);stroke:rgb(0,128,0);stroke-width:0.2");
|
|
}
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
try
|
|
{
|
|
// Note, file location: trunk/libs/geometry/example/data
|
|
// update path below if necessary
|
|
read_wkt_and_project_and_map_svg(
|
|
"../../../../example/data/world.wkt",
|
|
"world4.svg");
|
|
}
|
|
catch(std::exception const& e)
|
|
{
|
|
std::cout << "Exception: " << e.what() << std::endl;
|
|
return 1;
|
|
}
|
|
catch(std::string const& s)
|
|
{
|
|
std::cout << "Exception: " << s << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|