7326b55b32
[SVN r76367]
119 lines
4.2 KiB
C++
119 lines
4.2 KiB
C++
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
//
|
|
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
|
//
|
|
// 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)
|
|
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
// SOCI example
|
|
|
|
// c: using WKB to retrieve geometries
|
|
|
|
// SOCI is a generic C++ template interface to access relational databases
|
|
|
|
// To build and run this example, see comments in example a
|
|
// Alternatively compile composing and executing compiler command directoy in examples directory,
|
|
// for example using GCC compiler:
|
|
// g++ -I../../../boost -I/home/mloskot/usr/include/soci \
|
|
// -I /home/mloskot/usr/include/soci/postgresql -I/usr/include/postgresql \
|
|
// -L/home/mloskot/usr/lib -lsoci_core-gcc-3_0 -lsoci_postgresql-gcc-3_0 x03_c_soci_example.cpp
|
|
|
|
#include <soci.h>
|
|
#include <soci-postgresql.h>
|
|
|
|
#include <exception>
|
|
#include <iostream>
|
|
#include <iterator>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <boost/geometry/geometry.hpp>
|
|
#include <boost/geometry/geometries/geometries.hpp>
|
|
#include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
|
|
#include <boost/geometry/extensions/gis/io/wkb/utility.hpp>
|
|
#include <boost/geometry/io/wkt/wkt.hpp>
|
|
|
|
// user-defined type with GGL geometry
|
|
struct tree
|
|
{
|
|
int id;
|
|
boost::geometry::model::point<float, 2, boost::geometry::cs::geographic<boost::geometry::degree> > location;
|
|
};
|
|
|
|
// conversion of row of result to user-defined type - performs WKB parsing
|
|
namespace soci
|
|
{
|
|
template <>
|
|
struct type_conversion<tree>
|
|
{
|
|
typedef soci::values base_type;
|
|
|
|
static void from_base(base_type const& v, soci::indicator ind, tree& value)
|
|
{
|
|
try
|
|
{
|
|
value.id = v.get<int>("id");
|
|
|
|
// intermediate step: hex-encoded binary string to raw WKB
|
|
std::string const& hex = v.get<std::string>("wkb");
|
|
std::vector<unsigned char> wkb;
|
|
if (!boost::geometry::hex2wkb(hex, std::back_inserter(wkb)))
|
|
throw std::runtime_error("hex2wkb translation failed");
|
|
|
|
// parse WKB and construct point geometry
|
|
if (!boost::geometry::read_wkb(wkb.begin(), wkb.end(), value.location))
|
|
throw std::runtime_error("read_wkb failed");
|
|
}
|
|
catch(const std::exception& e)
|
|
{
|
|
std::cout << e.what() << std::endl;
|
|
}
|
|
}
|
|
|
|
static void to_base(tree const& value, base_type& v, soci::indicator& ind)
|
|
{
|
|
throw std::runtime_error("todo: wkb writer not yet implemented");
|
|
}
|
|
};
|
|
}
|
|
|
|
int main()
|
|
{
|
|
try
|
|
{
|
|
// establish database connection
|
|
soci::session sql(soci::postgresql, "dbname=ggl user=ggl password=ggl");
|
|
|
|
// construct schema of table for trees (point geometries)
|
|
sql << "DELETE FROM geometry_columns WHERE f_table_name = 'trees'";
|
|
sql << "DROP TABLE IF EXISTS trees CASCADE";
|
|
sql << "CREATE TABLE trees (id INTEGER)";
|
|
sql << "SELECT AddGeometryColumn('trees', 'geom', -1, 'POINT', 2)";
|
|
|
|
// insert sample data using plain WKT input
|
|
sql << "INSERT INTO trees VALUES(1, ST_GeomFromText('POINT(1.23 2.34)', -1))";
|
|
sql << "INSERT INTO trees VALUES(2, ST_GeomFromText('POINT(3.45 4.56)', -1))";
|
|
sql << "INSERT INTO trees VALUES(3, ST_GeomFromText('POINT(5.67 6.78)', -1))";
|
|
sql << "INSERT INTO trees VALUES(4, ST_GeomFromText('POINT(7.89 9.01)', -1))";
|
|
|
|
// query data in WKB form and read to geometry object
|
|
typedef std::vector<tree> trees_t;
|
|
soci::rowset<tree> rows = (sql.prepare << "SELECT id, encode(ST_AsBinary(geom), 'hex') AS wkb FROM trees");
|
|
trees_t trees;
|
|
std::copy(rows.begin(), rows.end(), std::back_inserter(trees));
|
|
|
|
// print trees output
|
|
for (trees_t::const_iterator it = trees.begin(); it != trees.end(); ++it)
|
|
{
|
|
std::cout << "Tree #" << it->id << " located at\t" << boost::geometry::wkt(it->location) << std::endl;
|
|
}
|
|
}
|
|
catch (std::exception const &e)
|
|
{
|
|
std::cerr << "Error: " << e.what() << '\n';
|
|
}
|
|
return 0;
|
|
}
|
|
|