mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 05:24:02 +00:00
[examples] Update qt example
This commit is contained in:
parent
12cac83034
commit
6c173505d9
66
example/with_external_libs/common/read_countries.hpp
Normal file
66
example/with_external_libs/common/read_countries.hpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Boost.Geometry
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007-2024 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)
|
||||||
|
|
||||||
|
#ifndef READ_COUNTRIES_HPP
|
||||||
|
#define READ_COUNTRIES_HPP
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <boost/geometry/geometry.hpp>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Read an ASCII file containing WKT's of either POLYGON or MULTIPOLYGON
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
template <typename Geometry>
|
||||||
|
std::vector<Geometry> read_countries(std::string const& filename)
|
||||||
|
{
|
||||||
|
std::vector<Geometry> geometries;
|
||||||
|
std::ifstream cpp_file(filename.c_str());
|
||||||
|
if (!cpp_file.is_open())
|
||||||
|
{
|
||||||
|
return geometries;
|
||||||
|
}
|
||||||
|
while (! cpp_file.eof() )
|
||||||
|
{
|
||||||
|
std::string line;
|
||||||
|
std::getline(cpp_file, line);
|
||||||
|
if (line.empty())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Geometry geometry;
|
||||||
|
if (line.substr(0, 4) == "POLY")
|
||||||
|
{
|
||||||
|
using polygon_t = std::decay_t<decltype(*geometry.begin())>;
|
||||||
|
polygon_t polygon;
|
||||||
|
boost::geometry::read_wkt(line, polygon);
|
||||||
|
geometry.push_back(polygon);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
boost::geometry::read_wkt(line, geometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
geometries.push_back(geometry);
|
||||||
|
}
|
||||||
|
return geometries;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the envelope of a collection of geometries
|
||||||
|
template <typename Box, typename Countries>
|
||||||
|
Box calculate_envelope(Countries const& countries)
|
||||||
|
{
|
||||||
|
Box box;
|
||||||
|
boost::geometry::assign_inverse(box);
|
||||||
|
|
||||||
|
for (auto const& country : countries)
|
||||||
|
{
|
||||||
|
boost::geometry::expand(box, boost::geometry::return_envelope<Box>(country));
|
||||||
|
}
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
example/with_external_libs/qt/CMakeLists.txt
Normal file
36
example/with_external_libs/qt/CMakeLists.txt
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# Boost.Geometry
|
||||||
|
# Example CMakeLists.txt building the Boost.Geometry with Qt example
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021-2024 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)
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(qt_world_mapper LANGUAGES CXX)
|
||||||
|
|
||||||
|
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)
|
||||||
|
|
||||||
|
qt_standard_project_setup()
|
||||||
|
|
||||||
|
qt_add_executable(${PROJECT_NAME}
|
||||||
|
qt_world_mapper.cpp
|
||||||
|
qt_world_mapper.hpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||||
|
WIN32_EXECUTABLE TRUE
|
||||||
|
MACOSX_BUNDLE TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(${PROJECT_NAME} PRIVATE
|
||||||
|
Qt6::Core
|
||||||
|
Qt6::Gui
|
||||||
|
Qt6::Widgets
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||||
|
..
|
||||||
|
../../../../..
|
||||||
|
)
|
64
example/with_external_libs/qt/README.md
Normal file
64
example/with_external_libs/qt/README.md
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
# 
|
||||||
|
|
||||||
|
# Qt
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
[Qt](https://www.qt.io/product/framework) is a stable and powerful open source framework for developing native cross-platform GUI applications in C++.
|
||||||
|
|
||||||
|
## Installing Qt
|
||||||
|
|
||||||
|
### Mac
|
||||||
|
|
||||||
|
On a Mac, installing Qt for this purpose is trivial:
|
||||||
|
|
||||||
|
`brew install qt`
|
||||||
|
|
||||||
|
And then you can use the standard CMake workflow.
|
||||||
|
|
||||||
|
During that, either ignore this warning: `Could NOT find WrapVulkanHeaders (missing: Vulkan_INCLUDE_DIR)`
|
||||||
|
|
||||||
|
or install vulkan-tools (`brew install vulkan-tools`), though for 2D applications, it might not be necessary.
|
||||||
|
|
||||||
|
### Linux Ubuntu
|
||||||
|
|
||||||
|
Since Qt 6.3 there is `qt_standard_project_setup()` used in the `CMakeLists.txt`.
|
||||||
|
|
||||||
|
If you have an older Qt version (on Ubuntu 22 you might have `QT6.2.4`), replace `qt_standard_project_setup` with:
|
||||||
|
|
||||||
|
```
|
||||||
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_AUTORCC ON)
|
||||||
|
```
|
||||||
|
|
||||||
|
And then you can use the standard CMake workflow.
|
||||||
|
|
||||||
|
If you want to use Qt with Vulkan, or get compiler errors or warnings because of Vulkan missing,
|
||||||
|
and you want to solve that, then install Vulkan as described [here](https://vulkan.lunarg.com/doc/sdk/1.3.239.0/linux/getting_started_ubuntu.html).
|
||||||
|
|
||||||
|
### Other platforms
|
||||||
|
|
||||||
|
Either you have Qt installed already, or you install it according to the [Qt documentation](https://doc.qt.io/qt-6/get-and-install-qt.html),
|
||||||
|
and change the `CMakeLists.txt` if necessary.
|
||||||
|
|
||||||
|
## Building this example
|
||||||
|
|
||||||
|
Assuming you want to build it with CMake, an example workflow is:
|
||||||
|
|
||||||
|
```
|
||||||
|
cd example/with_external_libs/qt
|
||||||
|
mkdir my_build_folder
|
||||||
|
cd my_build_folder
|
||||||
|
cmake .. -G Ninja
|
||||||
|
ninja
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running this example
|
||||||
|
|
||||||
|
You can pass an Ascii file with WKT polygons as the first command line argument. There are several
|
||||||
|
packed with Boost.Geometry as examples and as test data.
|
||||||
|
|
||||||
|
For example: `././qt_world_mapper.app/Contents/MacOS/qt_world_mapper ../../../data/world.wkt`
|
77
example/with_external_libs/qt/qt_world_mapper.cpp
Normal file
77
example/with_external_libs/qt/qt_world_mapper.cpp
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
// Boost.Geometry
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007-2024 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)
|
||||||
|
|
||||||
|
// Qt World Mapper Example
|
||||||
|
|
||||||
|
#include "qt_world_mapper.hpp"
|
||||||
|
#include "common/read_countries.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
#include <boost/geometry/geometries/register/point.hpp>
|
||||||
|
#include <boost/geometry/geometries/register/ring.hpp>
|
||||||
|
|
||||||
|
// Adapt a QPointF such that it can be handled by Boost.Geometry
|
||||||
|
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPointF, double, cs::cartesian, x, y, setX, setY)
|
||||||
|
|
||||||
|
// Adapt a QPolygonF as well.
|
||||||
|
// A QPolygonF has no holes (interiors) so it is similar to a Boost.Geometry ring
|
||||||
|
BOOST_GEOMETRY_REGISTER_RING(QPolygonF)
|
||||||
|
|
||||||
|
|
||||||
|
qt_world_mapper::qt_world_mapper(std::vector<country_type> const& countries, boost::geometry::model::box<point_2d> const& box, QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_countries(countries)
|
||||||
|
, m_box(box)
|
||||||
|
{
|
||||||
|
setPalette(QPalette(Qt::blue));
|
||||||
|
setAutoFillBackground(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void qt_world_mapper::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
map_transformer_type transformer(m_box, this->width(), this->height());
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setBrush(Qt::green);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
for(auto const& country : m_countries)
|
||||||
|
{
|
||||||
|
for(auto const& polygon : country)
|
||||||
|
{
|
||||||
|
// This is the essention:
|
||||||
|
// Directly transform from a multi_polygon (ring-type) to a QPolygonF
|
||||||
|
QPolygonF qring;
|
||||||
|
boost::geometry::transform(boost::geometry::exterior_ring(polygon), qring, transformer);
|
||||||
|
painter.drawPolygon(qring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
const std::string filename = argc > 1 ? argv[1] : "../../../data/world.wkt";
|
||||||
|
const auto countries = read_countries<country_type>(filename);
|
||||||
|
if (countries.empty())
|
||||||
|
{
|
||||||
|
std::cout << "No countries read" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto box = calculate_envelope<boost::geometry::model::box<point_2d>>(countries);
|
||||||
|
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
qt_world_mapper mapper(countries, box);
|
||||||
|
mapper.setWindowTitle("Boost.Geometry for Qt - Hello World!");
|
||||||
|
mapper.setGeometry(100, 100, 1024, 768);
|
||||||
|
mapper.show();
|
||||||
|
return app.exec();
|
||||||
|
}
|
47
example/with_external_libs/qt/qt_world_mapper.hpp
Normal file
47
example/with_external_libs/qt/qt_world_mapper.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Boost.Geometry
|
||||||
|
//
|
||||||
|
// Copyright (c) 2007-2024 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)
|
||||||
|
|
||||||
|
// Qt World Mapper Example
|
||||||
|
|
||||||
|
#ifndef QT_WORLD_MAPPER_H
|
||||||
|
#define QT_WORLD_MAPPER_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include <boost/geometry/geometry.hpp>
|
||||||
|
|
||||||
|
#include <boost/geometry/geometries/geometries.hpp>
|
||||||
|
|
||||||
|
using point_2d = boost::geometry::model::d2::point_xy<double>;
|
||||||
|
using country_type = boost::geometry::model::multi_polygon
|
||||||
|
<
|
||||||
|
boost::geometry::model::polygon<point_2d>
|
||||||
|
>;
|
||||||
|
|
||||||
|
class qt_world_mapper : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
qt_world_mapper(std::vector<country_type> const& countries, boost::geometry::model::box<point_2d> const& box, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
using map_transformer_type = boost::geometry::strategy::transform::map_transformer
|
||||||
|
<
|
||||||
|
double, 2, 2,
|
||||||
|
true, true
|
||||||
|
>;
|
||||||
|
|
||||||
|
std::vector<country_type> m_countries;
|
||||||
|
boost::geometry::model::box<point_2d> m_box;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.8...3.20)
|
|||||||
|
|
||||||
project(wx_widgets_world_mapper)
|
project(wx_widgets_world_mapper)
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME} x04_wxwidgets_world_mapper.cpp)
|
add_executable(${PROJECT_NAME} wxwidgets_world_mapper.cpp)
|
||||||
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
|
target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_14)
|
||||||
|
|
||||||
# Link the wxWidgets libraries to our executable
|
# Link the wxWidgets libraries to our executable
|
||||||
@ -21,7 +21,7 @@ target_link_libraries(${PROJECT_NAME} wxWidgets::wxWidgets)
|
|||||||
|
|
||||||
# Link the Boost.Geometry library to our executable
|
# Link the Boost.Geometry library to our executable
|
||||||
# By default, it is assumed to be relative to this directory.
|
# By default, it is assumed to be relative to this directory.
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ../../../../..)
|
target_include_directories(${PROJECT_NAME} PRIVATE .. ../../../../..)
|
||||||
|
|
||||||
# If this does not work, or you build from elsewhere
|
# If this does not work, or you build from elsewhere
|
||||||
# First set BOOST_ROOT
|
# First set BOOST_ROOT
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
// #define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
// #define EXAMPLE_WX_USE_GRAPHICS_CONTEXT 1
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/geometry/geometry.hpp>
|
#include <boost/geometry/geometry.hpp>
|
||||||
@ -34,6 +33,8 @@
|
|||||||
#include "wx/dcgraph.h"
|
#include "wx/dcgraph.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "common/read_countries.hpp"
|
||||||
|
|
||||||
using point_2d = boost::geometry::model::d2::point_xy<double>;
|
using point_2d = boost::geometry::model::d2::point_xy<double>;
|
||||||
using country_type = boost::geometry::model::multi_polygon
|
using country_type = boost::geometry::model::multi_polygon
|
||||||
<
|
<
|
||||||
@ -45,41 +46,6 @@ using country_type = boost::geometry::model::multi_polygon
|
|||||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, cs::cartesian, x, y)
|
BOOST_GEOMETRY_REGISTER_POINT_2D(wxPoint, int, cs::cartesian, x, y)
|
||||||
BOOST_GEOMETRY_REGISTER_POINT_2D(wxRealPoint, double, cs::cartesian, x, y)
|
BOOST_GEOMETRY_REGISTER_POINT_2D(wxRealPoint, double, cs::cartesian, x, y)
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Read an ASCII file containing WKT's of either POLYGON or MULTIPOLYGON
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
template <typename Geometry, typename Box>
|
|
||||||
inline void read_wkt(std::string const& filename, std::vector<Geometry>& geometries, Box& box)
|
|
||||||
{
|
|
||||||
std::ifstream cpp_file(filename.c_str());
|
|
||||||
if (cpp_file.is_open())
|
|
||||||
{
|
|
||||||
while (! cpp_file.eof() )
|
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
std::getline(cpp_file, line);
|
|
||||||
if (line.empty())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Geometry geometry;
|
|
||||||
if (line.substr(0, 4) == "POLY")
|
|
||||||
{
|
|
||||||
boost::geometry::model::polygon<point_2d> polygon;
|
|
||||||
boost::geometry::read_wkt(line, polygon);
|
|
||||||
geometry.push_back(polygon);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
boost::geometry::read_wkt(line, geometry);
|
|
||||||
}
|
|
||||||
|
|
||||||
geometries.push_back(geometry);
|
|
||||||
boost::geometry::expand(box, boost::geometry::return_envelope<Box>(geometry));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
class HelloWorldFrame: public wxFrame
|
class HelloWorldFrame: public wxFrame
|
||||||
@ -195,8 +161,8 @@ HelloWorldCanvas::HelloWorldCanvas(wxFrame *frame, const std::string& filename)
|
|||||||
, m_owner(frame)
|
, m_owner(frame)
|
||||||
, m_filename(filename)
|
, m_filename(filename)
|
||||||
{
|
{
|
||||||
boost::geometry::assign_inverse(m_box);
|
m_countries = read_countries<country_type>(m_filename);
|
||||||
read_wkt(m_filename, m_countries, m_box);
|
m_box = calculate_envelope<boost::geometry::model::box<point_2d>>(m_countries);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
||||||
//
|
|
||||||
// Copyright (c) 2007-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)
|
|
||||||
|
|
||||||
// Qt Example
|
|
||||||
|
|
||||||
// Qt is a well-known and often used platform independent windows library
|
|
||||||
|
|
||||||
// To build and run this example:
|
|
||||||
// 1) download (from http://qt.nokia.com), configure and make QT
|
|
||||||
// 2) if necessary, adapt Qt clause in include path (note there is a Qt property sheet)
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#include <QtGui>
|
|
||||||
|
|
||||||
#include <boost/geometry/geometry.hpp>
|
|
||||||
#include <boost/geometry/geometries/register/point.hpp>
|
|
||||||
#include <boost/geometry/geometries/register/ring.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
// Adapt a QPointF such that it can be handled by Boost.Geometry
|
|
||||||
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPointF, double, cs::cartesian, x, y, setX, setY)
|
|
||||||
|
|
||||||
// Adapt a QPolygonF as well.
|
|
||||||
// A QPolygonF has no holes (interiors) so it is similar to a Boost.Geometry ring
|
|
||||||
BOOST_GEOMETRY_REGISTER_RING(QPolygonF)
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
// This usage QApplication and QLabel is adapted from
|
|
||||||
// http://en.wikipedia.org/wiki/Qt_(toolkit)#Qt_hello_world
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
// Declare a Qt polygon. The Qt Polygon can be used
|
|
||||||
// in Boost.Geometry, just by its oneline registration above.
|
|
||||||
QPolygonF polygon;
|
|
||||||
|
|
||||||
// Use Qt to add points to polygon
|
|
||||||
polygon
|
|
||||||
<< QPointF(10, 20) << QPointF(20, 30)
|
|
||||||
<< QPointF(30, 20) << QPointF(20, 10)
|
|
||||||
<< QPointF(10, 20);
|
|
||||||
|
|
||||||
// Use Boost.Geometry e.g. to calculate area
|
|
||||||
std::ostringstream out;
|
|
||||||
out << "Boost.Geometry area: " << boost::geometry::area(polygon) << std::endl;
|
|
||||||
|
|
||||||
// Some functionality is defined in both Qt and Boost.Geometry
|
|
||||||
QPointF p(20,20);
|
|
||||||
out << "Qt contains: "
|
|
||||||
<< (polygon.containsPoint(p, Qt::WindingFill) ? "yes" : "no")
|
|
||||||
<< std::endl
|
|
||||||
<< "Boost.Geometry within: "
|
|
||||||
<< (boost::geometry::within(p, polygon) ? "yes" : "no")
|
|
||||||
<< std::endl;
|
|
||||||
// Detail: if point is ON boundary, Qt says yes, Boost.Geometry says no.
|
|
||||||
|
|
||||||
// Qt defines an iterator
|
|
||||||
// (which is required for of the Boost.Geometry ring-concept)
|
|
||||||
// such that Boost.Geometry can use the points of this polygon
|
|
||||||
QPolygonF::const_iterator it;
|
|
||||||
for (it = polygon.begin(); it != polygon.end(); ++it)
|
|
||||||
{
|
|
||||||
// Stream Delimiter-Separated, just to show something Boost.Geometry can do
|
|
||||||
out << boost::geometry::dsv(*it) << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stream the polygon as well
|
|
||||||
out << boost::geometry::dsv(polygon) << std::endl;
|
|
||||||
|
|
||||||
// Just show what we did in a label
|
|
||||||
QLabel label(out.str().c_str());
|
|
||||||
label.show();
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
||||||
|
|
@ -1,162 +0,0 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
||||||
//
|
|
||||||
// Copyright (c) 2007-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)
|
|
||||||
|
|
||||||
// Qt World Mapper Example
|
|
||||||
|
|
||||||
// Qt is a well-known and often used platform independent windows library
|
|
||||||
|
|
||||||
// To build and run this example:
|
|
||||||
// 1) download (from http://qt.nokia.com), configure and make QT
|
|
||||||
// 2) if necessary, adapt Qt clause in include path (note there is a Qt property sheet)
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
#include <QtGui>
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QObject>
|
|
||||||
#include <QPainter>
|
|
||||||
|
|
||||||
#include <boost/foreach.hpp>
|
|
||||||
|
|
||||||
#include <boost/geometry/geometry.hpp>
|
|
||||||
|
|
||||||
#include <boost/geometry/geometries/geometries.hpp>
|
|
||||||
#include <boost/geometry/geometries/multi_geometries.hpp>
|
|
||||||
#include <boost/geometry/geometries/point_xy.hpp>
|
|
||||||
|
|
||||||
#include <boost/geometry/geometries/register/point.hpp>
|
|
||||||
#include <boost/geometry/geometries/register/ring.hpp>
|
|
||||||
|
|
||||||
#include <boost/geometry/extensions/algorithms/selected.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Adapt a QPointF such that it can be handled by Boost.Geometry
|
|
||||||
BOOST_GEOMETRY_REGISTER_POINT_2D_GET_SET(QPointF, double, cs::cartesian, x, y, setX, setY)
|
|
||||||
|
|
||||||
// Adapt a QPolygonF as well.
|
|
||||||
// A QPolygonF has no holes (interiors) so it is similar to a Boost.Geometry ring
|
|
||||||
BOOST_GEOMETRY_REGISTER_RING(QPolygonF)
|
|
||||||
|
|
||||||
|
|
||||||
typedef boost::geometry::model::d2::point_xy<double> point_2d;
|
|
||||||
typedef boost::geometry::model::multi_polygon
|
|
||||||
<
|
|
||||||
boost::geometry::model::polygon<point_2d>
|
|
||||||
> country_type;
|
|
||||||
|
|
||||||
|
|
||||||
class WorldMapper : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WorldMapper(std::vector<country_type> const& countries, boost::geometry::model::box<point_2d> const& box)
|
|
||||||
: m_countries(countries)
|
|
||||||
, m_box(box)
|
|
||||||
{
|
|
||||||
setPalette(QPalette(QColor(200, 250, 250)));
|
|
||||||
setAutoFillBackground(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paintEvent(QPaintEvent*)
|
|
||||||
{
|
|
||||||
map_transformer_type transformer(m_box, this->width(), this->height());
|
|
||||||
|
|
||||||
QPainter painter(this);
|
|
||||||
painter.setBrush(Qt::green);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
BOOST_FOREACH(country_type const& country, m_countries)
|
|
||||||
{
|
|
||||||
typedef boost::range_value<country_type>::type polygon_type;
|
|
||||||
BOOST_FOREACH(polygon_type const& polygon, country)
|
|
||||||
{
|
|
||||||
typedef boost::geometry::ring_type<polygon_type>::type ring_type;
|
|
||||||
ring_type const& ring = boost::geometry::exterior_ring(polygon);
|
|
||||||
|
|
||||||
// This is the essention:
|
|
||||||
// Directly transform from a multi_polygon (ring-type) to a QPolygonF
|
|
||||||
QPolygonF qring;
|
|
||||||
boost::geometry::transform(ring, qring, transformer);
|
|
||||||
|
|
||||||
painter.drawPolygon(qring);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef boost::geometry::strategy::transform::map_transformer
|
|
||||||
<
|
|
||||||
double, 2, 2,
|
|
||||||
true, true
|
|
||||||
> map_transformer_type;
|
|
||||||
|
|
||||||
std::vector<country_type> const& m_countries;
|
|
||||||
boost::geometry::model::box<point_2d> const& m_box;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class MapperWidget : public QWidget
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MapperWidget(std::vector<country_type> const& countries, boost::geometry::model::box<point_2d> const& box, QWidget *parent = 0)
|
|
||||||
: QWidget(parent)
|
|
||||||
{
|
|
||||||
WorldMapper* mapper = new WorldMapper(countries, box);
|
|
||||||
|
|
||||||
QPushButton *quit = new QPushButton(tr("Quit"));
|
|
||||||
quit->setFont(QFont("Times", 18, QFont::Bold));
|
|
||||||
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
|
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout;
|
|
||||||
layout->addWidget(mapper);
|
|
||||||
layout->addWidget(quit);
|
|
||||||
setLayout(layout);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// Read an ASCII file containing WKT's
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
template <typename Geometry, typename Box>
|
|
||||||
inline void read_wkt(std::string const& filename, std::vector<Geometry>& geometries, Box& box)
|
|
||||||
{
|
|
||||||
std::ifstream cpp_file(filename.c_str());
|
|
||||||
if (cpp_file.is_open())
|
|
||||||
{
|
|
||||||
while (! cpp_file.eof() )
|
|
||||||
{
|
|
||||||
std::string line;
|
|
||||||
std::getline(cpp_file, line);
|
|
||||||
if (! line.empty())
|
|
||||||
{
|
|
||||||
Geometry geometry;
|
|
||||||
boost::geometry::read_wkt(line, geometry);
|
|
||||||
geometries.push_back(geometry);
|
|
||||||
boost::geometry::expand(box, boost::geometry::return_envelope<Box>(geometry));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
std::vector<country_type> countries;
|
|
||||||
boost::geometry::model::box<point_2d> box;
|
|
||||||
boost::geometry::assign_inverse(box);
|
|
||||||
read_wkt("../data/world.wkt", countries, box);
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
MapperWidget widget(countries, box);
|
|
||||||
widget.setWindowTitle("Boost.Geometry for Qt - Hello World!");
|
|
||||||
widget.setGeometry(50, 50, 800, 500);
|
|
||||||
widget.show();
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
||||||
//
|
|
||||||
// Copyright Barend Gehrels 2011, Geodan, 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)
|
|
||||||
|
|
||||||
Qt World Mapper example
|
|
||||||
|
|
||||||
It will show a basic Qt Widget, displaying world countries
|
|
||||||
|
|
||||||
To compile this program:
|
|
||||||
|
|
||||||
Install Qt (if not done before)
|
|
||||||
|
|
||||||
Using Linux/gcc
|
|
||||||
- install Qt with sudo apt-get install libqt4-dev
|
|
||||||
- run qmake -project
|
|
||||||
- edit the generated file "with_external_libs.pro" and delete all lines but the x06_qt_world_mapper.cpp
|
|
||||||
- run qmake
|
|
||||||
- edit the generated Makefile, if necessary, and add -I../../../.. to include Boost and Boost.Geometry
|
|
||||||
- run make
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user