保存数据的第一步是要把数据解析出来,然后根据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 ); }