保存数据的第一步是要把数据解析出来,然后根据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<string>
using std::string;
//单个POI数据结构
//根据PAS文件中对数据描述构建
//Name为POI名字
//PinYin为POI名字拼音
//Code为POI编码
//categoryCode为POI图层类别码
class SPoint :
public Geometry,public Element
{
private:
char *Name;
char *PinYin;
//int Code;
int CategoryCode;
public:
SPoint(void);
~SPoint(void);
void setName(char *Name);
char* getName();
void setPinYin(char *PinYin);
char *getPinYin();
//void setCode(int Code);
//int getCode();
void setCategoryCode(int CategoryCode);
int getCategoryCode();
};
list<SPoint> mPoint;
二、原始数据解析
这一口根据情况不同方法也不同,有解析shapefile的,有解析mapinfo数据的,也有直接解析二进制数据的。鄙人是直接解析二进制数据。由于工作性质和数据安全性原因,这一步就省略。
三、数据保存
定义GDAL驱动,根据GDAL规则来保存shapefile数据。
//保存点数据
void savePoint()
{
mPolygon.clear();
mPolyline.clear();
char *FilePath = "E:\\data\\point.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();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
CPLSetConfigOption("SHAPE_ENCODING","CP936");
//定义驱动
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, wkbPoint, NULL );
if( poLayer == NULL )
{
printf( "创建图层失败.\n" );
return;
}
//创建属性字段
//定义属性字段code、type和name
OGRFieldDefn codeField("code", OFTInteger );
OGRFieldDefn typeField("type", OFTString );
OGRFieldDefn nameField("name", OFTString );
//设置code和type字段的宽度
codeField.SetWidth(32);
typeField.SetWidth(32);
nameField.SetWidth(100);
//创建字段
if( poLayer->CreateField( &codeField ) != OGRERR_NONE )
{
printf( "创建字段codeField失败.\n" );
return;
}
if( poLayer->CreateField( &typeField ) != OGRERR_NONE )
{
printf( "创建字段codeField失败.\n" );
return;
}
if( poLayer->CreateField( &nameField ) != OGRERR_NONE )
{
printf( "创建字段name失败.\n" );
return;
}
list<SPoint>::iterator itor;
for (itor = mPoint.begin();itor != mPoint.end();itor++)
{
//创建第i个点
OGRFeature *poFeature=OGRFeature::CreateFeature( poLayer->GetLayerDefn());
//设置第i条线的属性
poFeature->SetField("code",itor->getCode());
poFeature->SetField("type", itor->getType());
poFeature->SetField("name", itor->getName());
//定义Point,并设置其XY坐标
OGRPoint *poPoint = new OGRPoint();
poPoint->setX(itor->getX());
poPoint->setY(itor->getY());
poFeature->SetGeometry(poPoint);
if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
{
printf( "创建point失败.\n" );
return;
}
OGRFeature::DestroyFeature( poFeature );
}
OGRDataSource::DestroyDataSource( poDS );
}