如何使用带有c ++的ogr库在ESRI shapefile中提取几何的顶点

Sep*_*our 7 c++ shapefile visual-studio-2010 gdal ogr

我已经回答了这个问题,也改变了从问题的标题如何访问使用OGR库和C++多边形层顶点如何提取使用OGR库和C++在ESRI shapefile中的几何形状的顶点.该代码可用于使用OpenGL显示形状.
任何使其更好的建议将不胜感激.
例如,你认为我应该使用图层的投影来增强OpenGL中的视图吗?如何使用投影并将其应用于OpenGL窗口?

到目前为止,我已经尝试过这些类来提取多边形的顶点:

  • OGRPolygon:它没有任何方法来获取顶点数,起点和终点.
  • OGRLineString:当我使用getNumPoints()方法时,我的图层中的所有面要素都得到1.
  • OGRLinearRing:当我使用getNumPoints()方法时,我的图层中的所有面要素都得到1.

我该怎么做才能获得多边形shapefile中的顶点数和顶点坐标,以便在OpenGL窗口中绘制多边形.

Sep*_*our 8

我找到了答案:
您应该关注有关ESRI shapefile的一些信息.

  • 点图层:只能包含wkbpoint类型的功能.因此,您可以定义名为MyPoint2D的数据结构,并将此图层的坐标存储在具有MyPoint2D类型成员的 向量中.

  • 多点层:只能具有wkbMultipoint类型的功能.因此,您可以将每个要素存储在具有MyPoint2D类型成员的向量中,并且这些向量的集合将保存图层中所有要素的坐标.

  • 折线图层:可以具有类型为wkbLineStringwkbMultiLineString的特征.因此,您可以拥有一个数据结构MyLine2D,它是一个带有MyPoint2D成员的向量,一个成员类型为MyLine2D的向量将保存LineFeature,最后图层中的 要素将存储在具有LineFeature类型成员的向量中.

  • 多边形图层:关于多边形,你应该知道每个多边形由一个外环和几个内环组成(这是我真正的问题,这让我提出了问题).并且该层可以具有类型为 wkbPolygonwkbMultiPolygon的特征.

所以首先我们应该定义这些数据结构:

//data structure for points
typedef struct MyPoint2D
{
double dX;
double dY;
}MyPoint2D;

//Holds Coordinates of Point Shapefile
vector<MyPoint2D>PointLayer;

//data structure for a multipoint feature
typedef struct MultipointFeature
{
vector<MyPoint2D>PointsOfFeature;
}MultipointFeature;

//Holds Coordinates of multiPoint Shapefile
vector<MultipointFeature> MultipointLayer;

//data structure for lines
typedef struct MyLine2D
{
 vector<MyPoint2D> LineString;
}MyLine2D;

//data structure for a line feature
typedef struct LineFeature
{
vector<MyLine2D>LinesOfFeature;
}LineFeature;

//Holds Coordinates of Line Shapefile
vector<LineFeature> LineLayer;

//data structure for rings
typedef struct MyRing2D
{
vector<MyPoint2D> RingString;
bool IsClockwised;
}MyRing2D;

//data structure for polygons
typedef struct MyPolygon2D
{
vector<MyRing2D>Polygon;
}MyPolygon2D;

//data structure for a polygon feature
typedef struct PolygonFeature
{
vector<MyPolygon2D>PolygonsOfFeature;
}PolygonFeature;

//Holds Coordinates of Polygon Shapefile
vector<PolygonFeature> PolygonLayer;

//data structure to hold bounding box
typedef struct SBoundingBox
{
 float fMaxX;
 float fMaxY;
 float fMinX;
 float fMinY;
 }SBoundingBox;

//Bounding Box of Shapefile 
SBoundingBox sBoundingBox;  
Run Code Online (Sandbox Code Playgroud)

这是整个代码,我用它来提取ESRI的shapefile中的顶点坐标:

void OpenShapeFile(char* filename)
{
OGRErr error;
OGRDataSource *poDataSource;
poDataSource = OGRSFDriverRegistrar::Open(filename,false);
OGRLayer *poLayer;
poLayer = poDataSource ->GetLayer(0);
OGREnvelope Envelope;
error = poLayer ->GetExtent(&Envelope,true);
sBoundingBox.fMaxX = Envelope.MaxX;
sBoundingBox.fMaxY = Envelope.MaxY;
sBoundingBox.fMinX = Envelope.MinX;
sBoundingBox.fMinY = Envelope.MinY;  

OGRwkbGeometryType LayerGeometryType = poLayer ->GetGeomType();
int NumberOfFeatures = poLayer ->GetFeatureCount(true);
poLayer ->ResetReading();  

//Point Shapefile
if ( wkbFlatten ( LayerGeometryType ) == wkbPoint )
{
   OGRFeature *poFeature;
   for ( int i = 0; i < NumberOfFeatures; i++ )
   {
       poFeature = poLayer ->GetNextFeature();
       OGRGeometry *poGeometry;
       poGeometry = poFeature ->GetGeometryRef();
       if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbPoint )
       {
           OGRPoint *poPoint = ( OGRPoint * )poGeometry;
           MyPoint2D pt;
           pt.dX = poPoint ->getX();
           pt.dY = poPoint ->getY();
           PointLayer.push_back(pt);
       }
       OGRFeature::DestroyFeature(poFeature);
   }
}  

//Multipoint Shapefile
if ( wkbFlatten ( LayerGeometryType ) == wkbMultiPoint )
{
   OGRFeature *poFeature;
   MultipointFeature MultiPoint;
   for ( int i = 0; i < NumberOfFeatures; i++ )
   {
       poFeature = poLayer ->GetNextFeature();
       OGRGeometry *poGeometry;
       poGeometry = poFeature ->GetGeometryRef();
       if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbMultiPoint )
       {
           OGRMultiPoint *poMultipoint = ( OGRMultiPoint * )poGeometry;
           int NumberOfGeometries = poMultipoint ->getNumGeometries();
           MultiPoint.PointsOfFeature.resize( NumberOfGeometries );
           for ( int j = 0; j < NumberOfGeometries; j++ )
           {
               OGRGeometry *poPointGeometry = poMultipoint ->getGeometryRef(j);
               OGRPoint *poPoint = ( OGRPoint * )poPointGeometry;
               MyPoint2D pt;
               pt.dX = poPoint ->getX();
               pt.dY = poPoint ->getY();
               MultiPoint.PointsOfFeature.at(j) = pt;
           }
           MultipointLayer.push_back(MultiPoint);
       }
       OGRFeature::DestroyFeature(poFeature);
   }
}  

//Polyline Shapefile
if ( wkbFlatten ( LayerGeometryType ) == wkbLineString )
{
   OGRFeature *poFeature;
   LineFeature Polyline;
   OGRPoint ptTemp;
   for ( int i = 0; i < NumberOfFeatures; i++ )
   {
       poFeature = poLayer ->GetNextFeature();
       OGRGeometry *poGeometry;
       poGeometry = poFeature ->GetGeometryRef();
       if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbLineString  )
       {
           OGRLineString *poLineString = ( OGRLineString * )poGeometry;
           Polyline.LinesOfFeature.resize(1);
           int NumberOfVertices = poLineString ->getNumPoints();
           Polyline.LinesOfFeature.at(0).LineString.resize(NumberOfVertices);
           for ( int k = 0; k < NumberOfVertices; k++ )
           {
               poLineString ->getPoint(k,&ptTemp);
               MyPoint2D pt;
               pt.dX = ptTemp.getX();
               pt.dY = ptTemp.getY();
               Polyline.LinesOfFeature.at(0).LineString.at(k) = pt;
           }
           LineLayer.push_back(Polyline);
       }
       else if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbMultiLineString )
       {
           OGRMultiLineString *poMultiLineString = ( OGRMultiLineString * )poGeometry;
           int NumberOfGeometries = poMultiLineString ->getNumGeometries();
           Polyline.LinesOfFeature.resize(NumberOfGeometries);
           for ( int j = 0; j < NumberOfGeometries; j++ )
           {
               OGRGeometry *poLineGeometry = poMultiLineString ->getGeometryRef(j);
               OGRLineString *poLineString = ( OGRLineString * )poLineGeometry;
               int NumberOfVertices = poLineString ->getNumPoints();
               Polyline.LinesOfFeature.at(j).LineString.resize(NumberOfVertices);
               for ( int k = 0; k < NumberOfVertices; k++ )
               {
                   poLineString ->getPoint(k,&ptTemp);
                   MyPoint2D pt;
                   pt.dX = ptTemp.getX();
                   pt.dY = ptTemp.getY();
                   Polyline.LinesOfFeature.at(j).LineString.at(k) = pt;
               }
           }
           LineLayer.push_back(Polyline);
       }
       OGRFeature::DestroyFeature(poFeature);
   }
}  

//Polygon Shapefile
if ( wkbFlatten ( LayerGeometryType ) == wkbPolygon )
{
   OGRFeature *poFeature;
   PolygonFeature Polygon;
   OGRPoint ptTemp;
   for ( int i = 0; i < NumberOfFeatures; i++ )
   {
       poFeature = poLayer ->GetNextFeature();
       OGRGeometry *poGeometry;
       poGeometry = poFeature ->GetGeometryRef();
       if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbPolygon )
       {
           OGRPolygon *poPolygon = ( OGRPolygon * )poGeometry;
           Polygon.PolygonsOfFeature.resize(1);
           int NumberOfInnerRings = poPolygon ->getNumInteriorRings();
           OGRLinearRing *poExteriorRing = poPolygon ->getExteriorRing();
           Polygon.PolygonsOfFeature.at(0).Polygon.resize(NumberOfInnerRings+1);
           Polygon.PolygonsOfFeature.at(0).Polygon.at(0).IsClockwised = poExteriorRing ->isClockwise();
           int NumberOfExteriorRingVertices = poExteriorRing ->getNumPoints();
           Polygon.PolygonsOfFeature.at(0).Polygon.at(0).RingString.resize(NumberOfExteriorRingVertices);
           for ( int k = 0; k < NumberOfExteriorRingVertices; k++ )
           {
               poExteriorRing ->getPoint(k,&ptTemp);
               MyPoint2D pt;
               pt.dX = ptTemp.getX();
               pt.dY = ptTemp.getY();
               Polygon.PolygonsOfFeature.at(0).Polygon.at(0).RingString.at(k) = pt;
           }
           for ( int h = 1; h <= NumberOfInnerRings; h++ )
           {
               OGRLinearRing *poInteriorRing = poPolygon ->getInteriorRing(h-1);
               Polygon.PolygonsOfFeature.at(0).Polygon.at(h).IsClockwised = poInteriorRing ->isClockwise();
               int NumberOfInteriorRingVertices = poInteriorRing ->getNumPoints();
               Polygon.PolygonsOfFeature.at(0).Polygon.at(h).RingString.resize(NumberOfInteriorRingVertices);
               for ( int k = 0; k < NumberOfInteriorRingVertices; k++ )
               {
                   poInteriorRing ->getPoint(k,&ptTemp);
                   MyPoint2D pt;
                   pt.dX = ptTemp.getX();
                   pt.dY = ptTemp.getY();
                   Polygon.PolygonsOfFeature.at(0).Polygon.at(h).RingString.at(k) = pt;
               }
           }
               PolygonLayer.push_back(Polygon);
       }
       else if ( poGeometry != NULL && wkbFlatten ( poGeometry ->getGeometryType() ) == wkbMultiPolygon )
       {
           OGRMultiPolygon *poMultiPolygon = ( OGRMultiPolygon * )poGeometry;
           int NumberOfGeometries = poMultiPolygon ->getNumGeometries();
           Polygon.PolygonsOfFeature.resize(NumberOfGeometries);
           for ( int j = 0; j < NumberOfGeometries; j++ )
           {
               OGRGeometry *poPolygonGeometry = poMultiPolygon ->getGeometryRef(j);
               OGRPolygon *poPolygon = ( OGRPolygon * )poPolygonGeometry;
               int NumberOfInnerRings = poPolygon ->getNumInteriorRings();
               OGRLinearRing *poExteriorRing = poPolygon ->getExteriorRing();
               Polygon.PolygonsOfFeature.at(j).Polygon.resize(NumberOfInnerRings+1);
               Polygon.PolygonsOfFeature.at(j).Polygon.at(0).IsClockwised = poExteriorRing ->isClockwise();
               int NumberOfExteriorRingVertices = poExteriorRing ->getNumPoints();
               Polygon.PolygonsOfFeature.at(j).Polygon.at(0).RingString.resize(NumberOfExteriorRingVertices);
               for ( int k = 0; k < NumberOfExteriorRingVertices; k++ )
               {
                   poExteriorRing ->getPoint(k,&ptTemp);
                   MyPoint2D pt;
                   pt.dX = ptTemp.getX();
                   pt.dY = ptTemp.getY();
                   Polygon.PolygonsOfFeature.at(j).Polygon.at(0).RingString.at(k) = pt;
               }
               for ( int h = 1; h <= NumberOfInnerRings; h++ )
               {
                   OGRLinearRing *poInteriorRing = poPolygon ->getInteriorRing(h-1);
                   Polygon.PolygonsOfFeature.at(j).Polygon.at(h).IsClockwised = poInteriorRing ->isClockwise();
                   int NumberOfInteriorRingVertices = poInteriorRing ->getNumPoints();
                   Polygon.PolygonsOfFeature.at(j).Polygon.at(h).RingString.resize(NumberOfInteriorRingVertices);
                   for ( int k = 0; k < NumberOfInteriorRingVertices; k++ )
                   {
                       poInteriorRing ->getPoint(k,&ptTemp);
                       MyPoint2D pt;
                       pt.dX = ptTemp.getX();
                       pt.dY = ptTemp.getY();
                       Polygon.PolygonsOfFeature.at(j).Polygon.at(h).RingString.at(k) = pt;
                   }
               }
           }
           PolygonLayer.push_back(Polygon);
       }
   }
   OGRFeature::DestroyFeature(poFeature);
}  

OGRDataSource::DestroyDataSource(poDataSource);
}
Run Code Online (Sandbox Code Playgroud)