x05_shapelib_example.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. //
  3. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  4. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  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. //
  9. // SHAPELIB example
  10. // Shapelib is a well-known and often used library to read (and write) shapefiles by Frank Warmerdam
  11. // To build and run this example:
  12. // 1) download shapelib from http://shapelib.maptools.org/
  13. // 2) extract and put the source "shpopen.cpp" in project or makefile
  14. // 3) download a shapefile, for example world countries from http://aprsworld.net/gisdata/world
  15. // Alternativelly, install Shapelib using OSGeo4W installer from http://trac.osgeo.org/osgeo4w/
  16. // that provides Windows binary packages
  17. #include "shapefil.h"
  18. #include <boost/geometry/geometry.hpp>
  19. #include <boost/geometry/geometries/geometries.hpp>
  20. #include <boost/geometry/geometries/point_xy.hpp>
  21. using namespace boost::geometry;
  22. template <typename T, typename F>
  23. void read_shapefile(const std::string& filename, std::vector<T>& polygons, F functor)
  24. {
  25. try
  26. {
  27. SHPHandle handle = SHPOpen(filename.c_str(), "rb");
  28. if (handle <= 0)
  29. {
  30. throw std::string("File " + filename + " not found");
  31. }
  32. int nShapeType, nEntities;
  33. double adfMinBound[4], adfMaxBound[4];
  34. SHPGetInfo(handle, &nEntities, &nShapeType, adfMinBound, adfMaxBound );
  35. for (int i = 0; i < nEntities; i++)
  36. {
  37. SHPObject* psShape = SHPReadObject(handle, i );
  38. // Read only polygons, and only those without holes
  39. if (psShape->nSHPType == SHPT_POLYGON && psShape->nParts == 1)
  40. {
  41. T polygon;
  42. functor(psShape, polygon);
  43. polygons.push_back(polygon);
  44. }
  45. SHPDestroyObject( psShape );
  46. }
  47. SHPClose(handle);
  48. }
  49. catch(const std::string& s)
  50. {
  51. throw s;
  52. }
  53. catch(...)
  54. {
  55. throw std::string("Other exception");
  56. }
  57. }
  58. template <typename T>
  59. void convert(SHPObject* psShape, T& polygon)
  60. {
  61. double* x = psShape->padfX;
  62. double* y = psShape->padfY;
  63. for (int v = 0; v < psShape->nVertices; v++)
  64. {
  65. typename point_type<T>::type point;
  66. assign_values(point, x[v], y[v]);
  67. append(polygon, point);
  68. }
  69. }
  70. int main()
  71. {
  72. std::string filename = "c:/data/spatial/shape/world_free/world.shp";
  73. typedef model::polygon<model::d2::point_xy<double> > polygon_2d;
  74. std::vector<polygon_2d> polygons;
  75. try
  76. {
  77. read_shapefile(filename, polygons, convert<polygon_2d>);
  78. }
  79. catch(const std::string& s)
  80. {
  81. std::cout << s << std::endl;
  82. return 1;
  83. }
  84. // Do something with the polygons, for example simplify them
  85. for (std::vector<polygon_2d>::iterator it = polygons.begin(); it != polygons.end(); it++)
  86. {
  87. polygon_2d p;
  88. simplify(*it, p, 0.01);
  89. std::cout << it->outer().size() << "," << p.outer().size() << std::endl;
  90. *it = p;
  91. }
  92. std::cout << "Simplified " << polygons.size() << std::endl;
  93. double sum = 0;
  94. for (std::vector<polygon_2d>::const_iterator it = polygons.begin(); it != polygons.end(); it++)
  95. {
  96. sum += area(*it);
  97. }
  98. std::cout << "Total area of " << polygons.size() << " polygons, total: " << sum << std::endl;
  99. return 0;
  100. }