x03_c_soci_example.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. // c: using WKB to retrieve geometries
  11. // SOCI is a generic C++ template interface to access relational databases
  12. // To build and run this example, see comments in example a
  13. // Alternatively compile composing and executing compiler command directoy in examples directory,
  14. // for example using GCC compiler:
  15. // g++ -I../../../boost -I/home/mloskot/usr/include/soci \
  16. // -I /home/mloskot/usr/include/soci/postgresql -I/usr/include/postgresql \
  17. // -L/home/mloskot/usr/lib -lsoci_core-gcc-3_0 -lsoci_postgresql-gcc-3_0 x03_c_soci_example.cpp
  18. #include <soci.h>
  19. #include <soci-postgresql.h>
  20. #include <exception>
  21. #include <iostream>
  22. #include <iterator>
  23. #include <string>
  24. #include <vector>
  25. #include <boost/geometry/geometry.hpp>
  26. #include <boost/geometry/geometries/geometries.hpp>
  27. #include <boost/geometry/extensions/gis/io/wkb/read_wkb.hpp>
  28. #include <boost/geometry/extensions/gis/io/wkb/utility.hpp>
  29. #include <boost/geometry/io/wkt/wkt.hpp>
  30. // user-defined type with GGL geometry
  31. struct tree
  32. {
  33. int id;
  34. boost::geometry::model::point<float, 2, boost::geometry::cs::geographic<boost::geometry::degree> > location;
  35. };
  36. // conversion of row of result to user-defined type - performs WKB parsing
  37. namespace soci
  38. {
  39. template <>
  40. struct type_conversion<tree>
  41. {
  42. typedef soci::values base_type;
  43. static void from_base(base_type const& v, soci::indicator ind, tree& value)
  44. {
  45. try
  46. {
  47. value.id = v.get<int>("id");
  48. // intermediate step: hex-encoded binary string to raw WKB
  49. std::string const& hex = v.get<std::string>("wkb");
  50. std::vector<unsigned char> wkb;
  51. if (!boost::geometry::hex2wkb(hex, std::back_inserter(wkb)))
  52. throw std::runtime_error("hex2wkb translation failed");
  53. // parse WKB and construct point geometry
  54. if (!boost::geometry::read_wkb(wkb.begin(), wkb.end(), value.location))
  55. throw std::runtime_error("read_wkb failed");
  56. }
  57. catch(const std::exception& e)
  58. {
  59. std::cout << e.what() << std::endl;
  60. }
  61. }
  62. static void to_base(tree const& value, base_type& v, soci::indicator& ind)
  63. {
  64. throw std::runtime_error("todo: wkb writer not yet implemented");
  65. }
  66. };
  67. }
  68. int main()
  69. {
  70. try
  71. {
  72. // establish database connection
  73. soci::session sql(soci::postgresql, "dbname=ggl user=ggl password=ggl");
  74. // construct schema of table for trees (point geometries)
  75. sql << "DELETE FROM geometry_columns WHERE f_table_name = 'trees'";
  76. sql << "DROP TABLE IF EXISTS trees CASCADE";
  77. sql << "CREATE TABLE trees (id INTEGER)";
  78. sql << "SELECT AddGeometryColumn('trees', 'geom', -1, 'POINT', 2)";
  79. // insert sample data using plain WKT input
  80. sql << "INSERT INTO trees VALUES(1, ST_GeomFromText('POINT(1.23 2.34)', -1))";
  81. sql << "INSERT INTO trees VALUES(2, ST_GeomFromText('POINT(3.45 4.56)', -1))";
  82. sql << "INSERT INTO trees VALUES(3, ST_GeomFromText('POINT(5.67 6.78)', -1))";
  83. sql << "INSERT INTO trees VALUES(4, ST_GeomFromText('POINT(7.89 9.01)', -1))";
  84. // query data in WKB form and read to geometry object
  85. typedef std::vector<tree> trees_t;
  86. soci::rowset<tree> rows = (sql.prepare << "SELECT id, encode(ST_AsBinary(geom), 'hex') AS wkb FROM trees");
  87. trees_t trees;
  88. std::copy(rows.begin(), rows.end(), std::back_inserter(trees));
  89. // print trees output
  90. for (trees_t::const_iterator it = trees.begin(); it != trees.end(); ++it)
  91. {
  92. std::cout << "Tree #" << it->id << " located at\t" << boost::geometry::wkt(it->location) << std::endl;
  93. }
  94. }
  95. catch (std::exception const &e)
  96. {
  97. std::cerr << "Error: " << e.what() << '\n';
  98. }
  99. return 0;
  100. }