OGRGeometry屬於OGR庫,OGR庫通常是和GDAL一起封裝供用戶使用的。GDAL&OGR庫支持了大多數地理數據格式的讀寫,通常用戶使用OGR庫可以完成大部分矢量相關的任務。但是OGR並沒有對特徵之間的空間關係計算提供原生支持。尤其是空間矢量之間的拓撲關係計算,其內部是採用的第三方庫geos。所以有時候我們乾脆直接使用geos進行矢量運算。這時候就有可能遇到OGRGeometry和geos::Geometry之間相互轉換的問題。
本文只列出了OGRGeometry轉geos::Geometry。反過來原理是一樣的。
兩者之間可以通過wkt和wkb相互轉換。
第二個方案採用wkb,這方法稍顯麻煩,因爲geos的WKBReader類是這樣定義的:
class GEOS_DLL WKBReader {
public:
geom::Geometry* read(std::istream &is);
輸入參數是std::istream,我整了一下午不知道如何構造std::istream。當然可以落盤,形成磁盤文件,但那不是我想要的。於是採用第二個方案:採用wkb,geos的WKTReader定義read函數如下:
class GEOS_DLL WKTReader {
public:
geom::Geometry* read(const std::string &wellKnownText);
我們發現,傳入的是string。
而OGRGeometry恰好有這麼個函數:
class CPL_DLL OGRGeometry
{
public:
virtual OGRErr exportToWkt( char ** ppszDstText,
OGRwkbVariant=wkbVariantOldOgc ) const = 0;
這就給我們了一個思路,順着思路實現:
geos::io::WKTReader wkt_read;
OGRFeature* fea = poLayer->GetFeature(i);
char * buff = nullptr;
fea->GetGeometryRef()->exportToWkt(&buff);
wkt_read.read(buff);
geoms = GeometryPtr(wkt_read.read(buff));
經過測試,該方法是可行的。順着這個思路就可以實現geos::Geometry轉到OGRGeometry。
多說一句,有時候使用geos庫會出現莫名其妙的崩潰問題。這些問題無非是內存重複銷燬引起的。新手多看看geos的代碼註釋,非常有營養。尤其是在涉及到指針傳遞的時候,看看註釋裏有沒有寫使用者獲得指針所有權等等。
這種情況在我剛接觸geos的時候是不是會出現,後來使用熟悉了就沒有問題了。