保存数据的第一步是要把数据解析出来,然后根据GDAL的规则进行数据point类型的shapefile数据生成。大概步骤为:
一、定义保存点要素数据的类
这里定义了两个基类:
//基类,保存要素类型,点、线、面
class Element
{
private:
char Type;
int Code;
public:
Element(void);
~Element(void);
void setType(char Type);
char getType();
void setCode(int Code);
int getCode();
};
//基类,保存要素中点的XY坐标
class Geometry
{
private:
double X;
double Y;
public:
Geometry(void);
~Geometry(void);
void setX(double X);
double getX();
void setY(double Y);
double getY();
};
保存面要素的类定义为:
#include "Element.h"
#include "Geometry.h"
#include<vector>
using namespace std;
//单个面
//Code为面编码
//pointSet为面中点集
class SPolygon :
public Element,public Geometry
{
private:
//int Code;
vector<Geometry> pointSet;
public:
SPolygon(void);
~SPolygon(void);
void clearPointSet();
//void setCode(int Code);
//int getCode();
void setPoints(vector<Geometry> pointSet);
vector<Geometry> getPoints();
Geometry getPointFromIndex(int index);
};
在保存面要素数据时,需要定义一个面要素的集合
//保存读取的面数据
list<SPolygon> mPolygon;
二、数据解析
三、数据保存
//保存面数据
void savePolygon()
{
char *FilePath = "E:\\data\\polygon.shp";
//判断文件是否存在,不存在就进行下面的保存操作,存在就先删除再保存
fstream f;
f.open(FilePath,ios::in);
//文件不存
if(!f)
{
f.close();
//remove(FilePath);
}
//文件存在,删除文件
else
{
f.close();
remove(FilePath);
}
//要保存的shapefile文件名,只保存文件名,不保存路径和.shp
char FileName[20];
char *p=strrchr(FilePath,'\\')+1;
strcpy(FileName,p);
int i=0,j=0;
while(i< 20 &&FileName[i]!='\0' &&FileName[i]!='.')
i++;
if(i !=20) FileName[i]='\0';
//注册OGR所有驱动
GDALAllRegister();
OGRRegisterAll();
//定义驱动
const char *pszDriverName = "ESRI Shapefile";
OGRSFDriver *poDriver;
poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(pszDriverName );
if( poDriver == NULL )
{
printf( "%s 驱动不可用.\n", pszDriverName );
return;
}
//创建filepath路径的文件
OGRDataSource *poDS;
poDS = poDriver->CreateDataSource( FilePath, NULL );
if( poDS == NULL )
{
printf( "创建文件s%失败.\n",FilePath );
return;
}
//定义图层,面图层
OGRLayer *poLayer;
poLayer = poDS->CreateLayer(FileName, NULL, wkbPolygon, NULL );
if( poLayer == NULL )
{
printf( "创建图层失败.\n" );
return;
}
//创建属性字段
//定义属性字段code和type
OGRFieldDefn codeField("code", OFTInteger);
OGRFieldDefn typeField("type", OFTString );
//设置code和type字段的宽度
codeField.SetWidth(32);
typeField.SetWidth(32);
//创建字段
if( poLayer->CreateField( &codeField ) != OGRERR_NONE )
{
printf( "创建字段codeField失败.\n" );
return;
}
if( poLayer->CreateField( &typeField ) != OGRERR_NONE )
{
printf( "创建字段codeField失败.\n" );
return;
}
list<SPolygon>::iterator itor;
for(itor=mPolygon.begin();itor!=mPolygon.end();itor++)
{
//创建第i个面
OGRFeature *poFeature=OGRFeature::CreateFeature( poLayer->GetLayerDefn() );
//设置第i条线的属性
poFeature->SetField("code",itor->getCode());
poFeature->SetField("type", itor->getType());
OGRPolygon *poPolygon = new OGRPolygon();
//定义Linear来保存面中数据
OGRLinearRing *poLinearRing = new OGRLinearRing();
//第i个面中包含的点数
int num=static_cast<int>(itor->getPoints().size());
poLinearRing->setNumPoints(num);
for(j=0;j<num;j++)
{
poLinearRing->setPoint(j,itor->getPointFromIndex(j).getX(),itor->getPointFromIndex(j).getY());
}
poPolygon->addRing(poLinearRing);
//poFeature->SetGeometryDirectly(poPolygon);
poFeature->SetGeometry(poPolygon);
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
{
printf( "创建polyline失败.\n" );
return;
}
OGRFeature::DestroyFeature( poFeature );
}
OGRDataSource::DestroyDataSource( poDS );
}