Wechat: yu389741| Email: gisdqy@163.com

Shop:https://www.giserdqy.com/shop

关于OGR读取多边形-Polygon(GDAL 2.0版本之前)



折腾了一天,之前有个老版本的GDAL 1.5.2的,读取多边形后提取多边形外边界代码如下:

OGRGeometry *pGeo=pFeature->GetGeometryRef();
OGRFeatureDefn *poFeaDfn=pFeature->GetDefnRef();  //要素的属性特征
if(poFeaDfn->GetGeomType()==wkbPolygon)  //判断特征是否为多边形
{  
    OGRPolygon *pPolygon=(OGRPolygon*)pGeo->clone();
    OGRLinearRing * poLR=pPolygon->getExteriorRing();
    int Num=poLR->getNumPoints();
}

在1.5.2版本的GDAL下没什么问题,结果用了一下新的版本的(1.9.2和1.11.4的,最新的2.0没试,因为2.0的OGR整体接口都变了),首先是判定是否为多边形那里,wkbPolygon报错,然后改成了wkbPolygon25D之后可以,但是提取出来的多边形外边界的Num都是1,百思不得其解,经过一天的调试和查找资料,才发现原来是shapfile中的多边形是带空洞的,带空洞的多边形在新的GDAL版本中读取出来的都是OGRMutPolygon,也就是多边形集合,而不单单是一个多边形了,所以原来的代码就需要修改如下:

OGRGeometry *pGeo=pFeature->GetGeometryRef();
OGRwkbGeometryType pGeoType=pGeo->getGeometryType();
if(pGeoType==wkbPolygon)
{
    OGRPolygon *pPolygon=(OGRPolygon*)pGeo;
}
else if(pGeoType==wkbMultiPolygon)  //这里就是带空洞多边形判断
{
    OGRMultiPolygon *pMulPolygon=(OGRMultiPolygon*)pGeo;
    OGRPolygon *pPolygon=NULL;
    for(int i=0;i<pMulPolygon->getNumGeometries();i++)
    {
        pPolygon=(OGRPolygon*)pMulPolygon->getGeometryRef(i);
    }
}

这样读出来的多边形就是正确的了。刚刚经过试验,应该是多边形集的最后一个是外边界最大的多边形,当然试验样本比较少,如果大家遇到了这个问题,可以参考一下,也可以在下面回复我。欢迎讨论。

————–2016年3月26日10:09 更新————-
为了避免版本号的问题,代码块替换如下:

...
OGRFeature *pFeature=NULL;
    pLayer->ResetReading();
    if(GDAL_VERSION_NUM<1600)  //GDAL版本小于1.6
    {
        while((pFeature=pLayer->GetNextFeature())!=NULL)
        {
            OGRGeometry *pGeo=pFeature->GetGeometryRef();
            OGRwkbGeometryType pGeoType=pGeo->getGeometryType();
            if(pGeoType==wkbPolygon25D)
            {
                OGRPolygon *pPolygon=(OGRPolygon*)pGeo;
            }
        }
    }
    else(GDAL_VERSION_NUM>=1600 || GDAL_VERSION_NUM<2000)  //GDAL版本大于1.6小于2.0
    {
        while((pFeature=pLayer->GetNextFeature())!=NULL)
        {
            OGRGeometry *pGeo=pFeature->GetGeometryRef();
            OGRwkbGeometryType pGeoType=pGeo->getGeometryType();
            if(pGeoType==wkbPolygon)
            {
                OGRPolygon *pPolygon=(OGRPolygon*)pGeo;
            }
            else if(pGeoType==wkbMultiPolygon)
            {
                OGRMultiPolygon *pMulPolygon=(OGRMultiPolygon*)pGeo;
                OGRPolygon *pPolygon=NULL;
                for(int i=0;i<pMulPolygon->getNumGeometries();i++)
                {
                    pPolygon=(OGRPolygon*)pMulPolygon->getGeometryRef(i);
                }
            }
        }
    }
    else
    {
        return;
    }
...

因为2.0之后的版本还没有研究过,只是知道接口都变了,所以先只好return了。

转载自:https://blog.csdn.net/sugeryao/article/details/50984454