2012年6月7日木曜日

boost::geometry と gdal/ogr

普通にやるには、GDAL/OGR にて、geos を有効にしてコンパイルすれば何の問題もないです。 単に boost::geometry を使ってみたかっただけという…  concepts ベースで書いてみようかなとも思ったんですが、OGRPolygon あたりの実装を concept で書くのは、自分には無理ゲーっぽいと思ったので相互変換のコードでお茶を濁しました。お陰で、だいぶ geometry の concept についても、わかってきたのですが・・・。このポストが、役に立つ人っているのかいな?という疑問が無いわけでもない…。
#include <ogrsf_frmts.h>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/assign.hpp>

BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);

namespace bg = boost::geometry;

typedef bg::model::d2::point_xy<double>    bg_point;
typedef bg::model::ring<bg_point>          bg_ring;
typedef bg::model::polygon<bg_point>       bg_polygon;
typedef bg::model::linestring<bg_point>    bg_linestring;

void point2ogrpoint(OGRPoint& lhs, const bg_point& rhs);
void line2ogrline(OGRLineString& lhs, const bg_linestring& rhs);
void poly2ogrpoly(OGRPolygon& lhs, const bg_polygon& rhs);
bg_point ogrpoint2point( const OGRPoint& rhs );
bg_linestring ogrline2line( const OGRLineString& rhs );
bg_polygon ogrpoly2poly( const OGRPolygon& rhs );



using namespace boost::assign;

void point2ogrpoint(OGRPoint& lhs, const bg_point& rhs) {
  lhs.setX( bg::get<0>(rhs) );
  lhs.setY( bg::get<1>(rhs) );
} 

void line2ogrline(OGRLineString& lhs, const bg_linestring& rhs) {
  lhs.setNumPoints( rhs.size() );
  for( int i = 0; i < rhs.size(); ++i ) {
    lhs.setPoint( i, bg::get<0>(rhs[i]), bg::get<1>(rhs[i]), 0.0 );
  }
}

void ring2ogrring(OGRLinearRing& lhs, const bg_ring& rhs) {
  lhs.setNumPoints( rhs.size() );
  for( int i = 0; i < rhs.size(); ++i ) {
    lhs.setPoint( i, bg::get<0>(rhs[i]), bg::get<1>(rhs[i]), 0.0 );
  }
}

void poly2ogrpoly(OGRPolygon& lhs, const bg_polygon& rhs) {
  { // external ring
    OGRLinearRing externalRing;
    ring2ogrring( externalRing, rhs.outer() );
    lhs.addRing( &externalRing );
  }
  // internal rings
  for( int i = 0; i < rhs.inners().size(); ++i ) {
    OGRLinearRing internalRing;
    ring2ogrring( internalRing, rhs.inners()[i] );
    lhs.addRing( &internalRing );
  }
}

bg_point ogrpoint2point( const OGRPoint& rhs ) {
  return bg_point( rhs.getX(), rhs.getY() );
}

bg_linestring ogrline2line( const OGRLineString& rhs ) {
  bg_linestring result;
  for( int i = 0; i < rhs.getNumPoints(); ++i ) {
    result += bg_point( rhs.getX(i), rhs.getY(i) );
  }
  return result;
}

bg_ring ogrring2ring( const OGRLinearRing& rhs ) {
  bg_ring result;
  for( int i = 0; i < rhs.getNumPoints(); ++i ) {
    result += bg_point( rhs.getX(i), rhs.getY(i) );
  }
  return result;
}

bg_polygon ogrpoly2poly( const OGRPolygon& rhs ) {
  bg_polygon result;
  result.outer() = ogrring2ring( *(rhs.getExteriorRing()) );
  int n = rhs.getNumInteriorRings();
  for( int i = 0; i < n; ++i ) {
    result.inners().push_back( ogrring2ring(*(rhs.getInteriorRing( i ))) );
  }
  return result;
}

0 件のコメント: