c++visual-studio-2010shapefilegdalogr

How to extract vertexes of geometries in ESRI shapefiles using ogr library with c++


I have answered the question and also changed the title of the question from How to access vertices in a polygon layer using ogr library with c++ to How to extract vertexes of geometries in ESRI shapefiles using ogr library with c++. The code can be used to show shapes with OpenGL.
Any suggestion to make it better will be appreciated.
For example do you think that I should use projection of the layer in order to enhance the view in OpenGL? How can I use the projection and apply it to the OpenGL window?

up to now I have tried these classes in order to extract the vertices of polygons:

what should I do to get the number of vertices and coordinates of vertices in a polygon shapefile in order to draw the polygon in an OpenGL window.


Solution

  • I found the answer:
    You should care some information about ESRI shapefiles.

    So at first we should define these data structures:

    //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;  
    

    And this is the whole code, I have used in order to extract the coordinates of vertexes in ESRI's shapefiles:

    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);
    }