• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 //
3 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
4 //
5 // Use, modification and distribution is subject to the Boost Software License,
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 // Boost.Geometry (aka GGL, Generic Geometry Library)
9 // SOCI example
10 
11 // d: using WKB to retrieve geometries
12 
13 // SOCI is a generic C++ template interface to access relational databases
14 
15 // To build and run this example, see comments in example a
16 // Alternatively compile composing and executing compiler command directoy in examples directory,
17 //    for example using GCC compiler:
18 //    g++ -I../../../boost -I/home/mloskot/usr/include/soci \
19 //        -I /home/mloskot/usr/include/soci/postgresql -I/usr/include/postgresql \
20 //        -L/home/mloskot/usr/lib -lsoci_core-gcc-3_0 -lsoci_postgresql-gcc-3_0 x03_c_soci_example.cpp
21 
22 #include <soci.h>
23 #include <soci-postgresql.h>
24 
25 #include <exception>
26 #include <iostream>
27 #include <iterator>
28 #include <string>
29 #include <vector>
30 
31 #include <boost/geometry.hpp>
32 
33 #include <boost/geometry/geometries/geometries.hpp>
34 #include <boost/geometry/geometries/point_xy.hpp>
35 
36 #include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
37 #include <boost/geometry/extensions/gis/io/wkb/utility.hpp>
38 
main()39 int main()
40 {
41     try
42     {
43         // establish database connection
44         soci::session sql(soci::postgresql, "dbname=ggl user=ggl password=ggl");
45 
46         // construct schema of table for trees (point geometries)
47         sql << "DELETE FROM geometry_columns WHERE f_table_name = 'parcels'";
48         sql << "DROP TABLE IF EXISTS parcels CASCADE";
49         sql << "CREATE TABLE parcels (id INTEGER)";
50         sql << "SELECT AddGeometryColumn('parcels', 'geom', -1, 'GEOMETRY', 2)";
51 
52         // insert sample data using plain WKT input
53         sql << "INSERT INTO parcels VALUES(1, ST_GeomFromText('POLYGON ((10 10, 10 20, 20 20, 20 15, 10 10))', -1))";
54         sql << "INSERT INTO parcels VALUES(2, ST_GeomFromText('POLYGON ((0 0, 4 0, 4 4, 0 4, 0 0))', -1))";
55         sql << "INSERT INTO parcels VALUES(3, ST_GeomFromText('POLYGON((1 1,2 1,2 2,1 2,1 1))', -1))";
56 
57         // query data in WKB form and read to geometry object
58         soci::rowset<std::string> rows = (sql.prepare << "SELECT encode(ST_AsBinary(geom), 'hex') AS wkb FROM parcels");
59 
60         // calculate area of each parcel
61         for (soci::rowset<std::string>::iterator it = rows.begin(); it != rows.end(); ++it)
62         {
63             // parse WKB and construct geometry object
64             std::string const& hex = *it;
65             std::vector<unsigned char> wkb;
66             if (!boost::geometry::hex2wkb(*it, std::back_inserter(wkb)))
67                 throw std::runtime_error("hex2wkb translation failed");
68 
69             boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > parcel;
70             if (!boost::geometry::read_wkb(wkb.begin(), wkb.end(), parcel))
71                 throw std::runtime_error("read_wkb failed");
72 
73             double a = boost::geometry::area(parcel);
74             std::cout << "Parcel geometry: " << boost::geometry::wkt(parcel) << std::endl
75                 << "\thas area is " << a << " in coordinate units" << std::endl;
76         }
77     }
78     catch (std::exception const &e)
79     {
80         std::cerr << "Error: " << e.what() << '\n';
81     }
82     return 0;
83 }
84 
85