Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Basic Shapefile to Shape2d
/*
* PolygonShapes.cpp
* HereToThere
*
* Created by David Wicks on 2/23/11.
* Copyright 2011 David Wicks. All rights reserved.
*
*/
#include "PolygonShapes.h"
#include "cinder/Filesystem.h"
#include "cinder/app/App.h"
using namespace std;
using namespace cinder;
namespace sansumbrella
{
namespace
{
void readPolygonShapefile( SHPHandle shp, DBFHandle dbf, int numEntities, Shape2d* shape, float mapWidth, float mapHeight )
{
for( int i = 0; i < numEntities; ++i )
{
SHPObject* obj = SHPReadObject( shp, i );
for( int partNumber = 0; partNumber < obj->nParts; partNumber++ )
{
int start = obj->nParts > 1 ? obj->panPartStart[partNumber] : 0;
int end = obj->nParts > 1 ? obj->panPartStart[ partNumber + 1 ] : obj->nVertices;
if( partNumber == obj->nParts-1 )
{
end = obj->nVertices;
}
Vec2f pt = geo::projectLatLon( obj->padfY[start], obj->padfX[start], mapWidth, mapHeight );
shape->moveTo( pt );
for( int v = start+1; v < end; ++v )
{
pt = geo::projectLatLon( obj->padfY[v], obj->padfX[v], mapWidth, mapHeight );
shape->lineTo( pt );
}
shape->close();
}
SHPDestroyObject( obj );
}
}
void readPolylineShapefile( SHPHandle shp, DBFHandle dbf, int numEntities, Shape2d* shape, float mapWidth, float mapHeight )
{
for( int i = 0; i < numEntities; ++i )
{
SHPObject* obj = SHPReadObject( shp, i );
for( int partNumber = 0; partNumber < obj->nParts; partNumber++ )
{
int start = obj->nParts > 1 ? obj->panPartStart[partNumber] : 0;
int end = obj->nParts > 1 ? obj->panPartStart[ partNumber + 1 ] : obj->nVertices;
if( partNumber == obj->nParts-1 )
{
end = obj->nVertices;
}
Vec2f pt = geo::projectLatLon( obj->padfY[start], obj->padfX[start], mapWidth, mapHeight );
shape->moveTo( pt );
for( int v = start+1; v < end; ++v )
{
pt = geo::projectLatLon( obj->padfY[v], obj->padfX[v], mapWidth, mapHeight );
shape->lineTo( pt );
}
}
SHPDestroyObject( obj );
}
}
void readPointShapefile( SHPHandle shp, DBFHandle dbf, int numEntities, Shape2d* shape, float mapWidth, float mapHeight )
{
}
} // end anonymous namespace
Shape2d geo::readShapefile( const string& shpLoc, const string& dbfLoc, float mapWidth, float mapHeight )
{
Shape2d shape;
if( !fs::exists( fs::path( shpLoc ) ) || !fs::exists( fs::path( dbfLoc ) ) )
{ // return empty shape if the shapefile doesn't exist
return shape;
}
SHPHandle shp = SHPOpen( shpLoc.c_str(), "rb" );
DBFHandle dbf = DBFOpen( dbfLoc.c_str(), "rb" );
int numEntities;
int shapeType;
double minBound[4];
double maxBound[4];
SHPGetInfo(shp, &numEntities, &shapeType, &minBound[0], &maxBound[0] );
switch ( shapeType ) {
case 1: //point
readPointShapefile( shp, dbf, numEntities, &shape, mapWidth, mapHeight );
break;
case 3: //polyline
readPolylineShapefile( shp, dbf, numEntities, &shape, mapWidth, mapHeight );
break;
case 5: //polygon
readPolygonShapefile( shp, dbf, numEntities, &shape, mapWidth, mapHeight );
break;
default:
break;
}
app::console() << "Reading shapefile: " << numEntities << ", " << shapeType << endl;
SHPClose( shp );
DBFClose( dbf );
return shape;
}
inline ci::Vec2f geo::projectLatLon( float x, float y, float mapWidth, float mapHeight )
{
return Vec2f( x, y ) * 1.0f;
}
}
/*
* PolygonShapes.h
* HereToThere
*
* Created by David Wicks on 2/23/11.
* Copyright 2011 David Wicks. All rights reserved.
*
*/
#pragma once
#include "cinder/Shape2d.h"
#include "shapefil.h"
namespace sansumbrella
{
namespace geo
{
//! factory method for creating shapes from shapefiles
//! supports polygon and polyline shapefiles
ci::Shape2d readShapefile( const std::string& shpLoc, const std::string& dbfLoc,
float mapWidth, float mapHeight );
inline ci::Vec2f projectLatLon( float x, float y, float mapWidth, float mapHeight );
}
}
@sansumbrella

This comment has been minimized.

Copy link
Owner Author

@sansumbrella sansumbrella commented Aug 12, 2011

Utilizes the ShapeLib C library:
http://shapelib.maptools.org/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment