Introduction
ESRI shapefiles are well known vector data formats used for Mapping a.k.a GIS applications. There are many open source softwares like JUMP, SharpMap that allow the users to view the shapefiles. This article focuses on rendering them in OpenGL console.
Background
Shapefiles hold geographic information in the form of points, lines and polygons. For instance- political boundaries like Countries, States are treated as Polygon shapefiles; linear features such as roads, rivers are Line shapefiles and; Airports or BusBays are sometimes treated as point shapefiles.
Using the Code
I assume that the intended audience is familiar with OpenGL and understands concepts like linking with static or dynamic libraries in Microsoft Visual Studio environment.
To parse the shapefile, I have used the Shapelib (http://shapelib.maptools.org/). Include the shapefile.h at the beginning. Make use of the shapelib.lib by adding shapelib\shapelib.lib to object/library Modules by going to Project>Settings>Link.
#include "shapelib\shapefil.h"
Call the following function to Open Shapefile by passing the .shp file name. The function parses the geographic coordinate information and stores them in the Vectors vPoints
, vLines
and vPolygons
.
void OpenShapeFile(char* fileName)
SBoundingBox
is a structure defined to hold the bounding box of the shapefile
. Bounding box coordinates are read in OpenShapeFile
function and assigned as glOrtho()
parameters, which would restrict the limits of display to the rectangle enveloping the area of interest.
glOrtho(sBoundingBox.fMinX, sBoundingBox.fMaxX,
sBoundingBox.fMinY,sBoundingBox.fMaxY,-1,1);
Finally, it is just a matter of setting appropriate OpenGL primitives(GL_POINTS
, GL_LINE_STRIP
, GL_LINE_LOOP
) to render Point, Line or Polygon type shapefile.
void draw()
{
glEnable(GL_POINT_SMOOTH) ;
glPointSize(5.0);
glBegin(GL_POINTS);
for(int i=0;i < vPoints.size();i++)
{
glVertex2f(vPoints[i].dX,vPoints[i].dY);
glEnd();
}
glColor3f (0.0, 1.0, 0.0);
for( i=0;i < vLines.size();i++)
{
glBegin(GL_LINE_STRIP);
for(int j=0;< vLines[i].vPointList.size();j++)
{
glVertex2f(vLines[i].vPointList[j].dX,vLines[i].vPointList[j].dY);
}
glEnd();
}
glColor3f(1.0,0.0, 0.0);
for( i=0;i < vPolygons.size();i++)
{
glBegin(GL_LINE_LOOP);
for(int j=0;j <vPolygons[i].vPointList.size();j++)
{
glVertex2f(vPolygons[i].vPointList[j].dX,
vPolygons[i].vPointList[j].dY);
}
glEnd();
}
glFlush();
}
Output
Points of Interest
It would be nice if someone comes up with ways to read/apply/reproject the .shp file by reading the projection information from .prj files accompanied with .shp files. PROJ.4
is an Open Source projection library if you want to give it a try.
Experimenting with pan and zoom features will be a good challenge.
Maintaining Aspect Ratio is a predominant feature in GIS applications. I leave it to you as another feature to explore.
History
- 29th December, 2008: Initial post