2021-08-10.shp

创建存储文件头的头文件 header.h
头中定义header类

class Header {
public:
	int FileCode;
	int Unused;
	int FileLength;
	int Version;
	int ShapeType;
	double Xmin;
	double Ymin;
	double Xmax;
	double Ymax;
	double Zmin;
	double Zmax;
	double Mmin;
	double Mmax;
};

创建存储格式的头文件 shape.h
point->line->polygon
先要创建一个point类

class Point { //点
public:
	double X;
	double Y;
	Point() {}
	void set_Point(double x, double y)
	{
		X = x;
		Y = y;

	}
};

然后根据polygon的属性 创建Shape 类

class Shape
{
public:
	int ShapeType;
	int RecordNumber;
	int ContentLength;
	double  Box[4];//边界
	int NumParts;
	int NumPoints;
	int* Parts = new int[NumParts];
	//以上是记录头,下面是记录的Points
	std::vector<Point> Points;//存储所有点的位置
	std::vector<PointM> PointMs;
	double M_Range[2];
	double* M_Array = new double[NumPoints];
};

然后创建Polygon 类继承Shape, 属性已经有了在类中只考虑向属性存储

class PolygonShape :public Shape {//多边
public:
	PolygonShape() {}
	void set_ShapeType(int a) {
		ShapeType = a;
	}
	void set_NumParts(int a) {
		NumParts = a;
	}
	void set_NumPoints(int a) {
		NumPoints = a;
	}
	void set_Box(double* a) {
		memcpy(Box, a, 4 * sizeof(double));
	}

	void set_Parts(int* a) {
		memcpy(this->Parts, a, NumParts * sizeof(int));
	}
	void set_Points(Point a) {
		Points.push_back(a);
	}
	void set_RecordNumber(int a) {
		RecordNumber = a;
	}
	void set_ContentLength(int a) {
		ContentLength = a;
	}
	void vectorclose() {
		Points.clear();
	}
};

需要向数据库中写入 创建 database.h 头文件

#include <iostream>
#include <string>
#include <mysql.h>
#include <string>
using namespace std;
MYSQL mysql; //实例MYSQL
MYSQL_FIELD* fd;//字段列数组 
char filed[32][100];//存字段名二维数组 可存32个字段
MYSQL_RES* res;//这个结构代表返回行的一个查询结果集合 
MYSQL_ROW column;//标识数据行的列 
char sql[150];//sql语句 
//连接数据库
bool ConnectDatabase() { 
		mysql_init(&mysql);//初始化mysql
		const char host[] = "localhost";
		const char username[] = "root";
		const char password[] = "7029";
		const char databasename[] = "shp";
		const int port = 3306;
		if (!(mysql_real_connect(&mysql, host, username, password, databasename, port, NULL, 0)))
		{cout << "error connect \n";
		 return false;
		}
		else {cout << "connect successful\n";
			return true;}
	    }
	//释放数据库的连接
	void freeconnect() {
		mysql_free_result(res); //释放一个结果集合使用的内存 
		mysql_close(&mysql);//关闭服务器连接 
	}
	//查询

bool QueryDatabase() {
		mysql_query(&mysql, "set names gbk");
	    //执行SQL语句  返回0 查询成功,返回1查询失败  
		if (mysql_query(&mysql, "select * from  header")) 
		{   printf("Query failed (%s)\n", mysql_error(&mysql));
			return false;}
		else
		{    printf("query success\n");
			}
	   //MYSQL_RES* res 存储行的查询结果
		res = mysql_store_result(&mysql);
	   //打印数据行数  
		printf("number of dataline returned: %d\n", mysql_affected_rows(&mysql));
		for (int i = 0; fd = mysql_fetch_field(res); i++)  //从结果中取得每一个字段存入fd中
		   {strcpy(field[i], fd->name);}
		int j = mysql_num_fields(res); // 获取列数  
		for (int i = 0; i < j; i++)  //打印字段  
				{printf("%10s\n", field[i]);}
		while (column = mysql_fetch_row(res))
			{for (int i = 0; i < j; i++)
				printf("%10s\t", column[i]);
				printf("\n");}
		return true;
		}
//创建表涉及到3个表 头文件,记录头,记录
bool create_table() {
		string str0 = "create table header_data(FileCode int , FileLength int ,Version int ,ShapeType int );";
	    string str1 = "create table record_header_data(RecordNumber int primary key , ContentLength int ,ShapeType int ,NumParts int ,NumPoints int);"; //可将RecordNumber作主键标识
		string str2 = "create table point_record_data(X double ,Y double ,RecordNumber int );";//可将RecordNumber作为此表的外键标识
		mysql_query(&mysql, str0.c_str());
		mysql_query(&mysql, str1.c_str());
		mysql_query(&mysql, str2.c_str());
		return 1;
}
//向头文件表插入数据
bool insert_header_data(int FileCode, int FileLength, int Version, int ShapeType, double xmin, double ymin, double xmax, double ymax ) {
		string str;
		str = "insert into header_data values(";
		str += to_string(FileCode);
		str += ",";
		str += to_string(FileLength);
		str += ",";
		str += to_string(Version);
		str += ",";
		str += to_string(ShapeType);
		str += ",";
		str += to_string(xmin);
		str += ",";
		str += to_string(ymin);
		str += ",";
		str += to_string(xmax);
		str += ",";
		str += to_string(ymax);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{	cout << "insert error";
			return false;}
		else {	cout << "insert  successful";
		    	return true;
		    	}
	}
//向记录头表插入数据
bool insert_recordheader_data(int RecordNumber, int ContentLength, int ShapeType, int NumParts,int NumPoints ) {
		string str;
		str = "insert into record_header_data values(";
		str += to_string(RecordNumber);
		str += ",";
		str += to_string(ContentLength);
		str += ",";
		str += to_string(ShapeType);
		str += ",";
		str += to_string(NumParts);
		str += ",";
		str += to_string(NumPoints);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{	cout << "insert error";
			return false;}
		else {	cout << "insert  successful";
			return true;}
	}
//向记录表插入数据
bool insert_pointrecord_data(double x,double y ,int record ) {
		string str;
		str = "insert into point_record_data values(";
		str += to_string(x);
		str += ",";
		str += to_string(y);
		str += ",";
		str += to_string(record);
		str += ");";
		cout << str;
		if (mysql_query(&mysql, str.c_str()))//执行sql语句 
		{   cout << "insert error\n";
		    return false;}
		else {
			cout << "insert  successful\n";
			return true;
		}
	}

然后主函数include 头文件 对.shp进行读取和写入

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include "shape.h"
#include "header.h"
#include"database.h"
using namespace std;
PolygonShape abc;//实例PolygonShape
Header header;//实例 header
std::vector<PolygonShape> polygon;//创建存储polygon的vector容器
//BT函数用来地址大小端的转换
template<class T>
T BT(T m)
{
	//union联合体内所有的数据公用一个内存
	union n_
	{
		T n;
		char mem[sizeof(T)];
	};
	n_ big, smal;
	big.n = m;
	for (int i = 0; i < sizeof(T); i++)
	{
		smal.mem[i] = big.mem[sizeof(T) - i - 1];//低位和高位转换
	}
	return smal.n;
}
//定义一个读取文件头的函数
void ReadFileHeard(FILE * ShpFile_fp) {
	// 读取坐标文件头的内容开始
	int Unused;
	fread(&header.FileCode, sizeof(int), 1, ShpFile_fp);
	header.FileCode = BT(header.FileCode);//FileCode为大端
	printf("FileCode=%d\n", header.FileCode);
	for (int i = 0;i < 5;i++)//根据格式 有五个空的int
		fread(&Unused, sizeof(int), 1, ShpFile_fp);
	//5个过后读取文件长度	
	fread(&header.FileLength, sizeof(int), 1, ShpFile_fp);
	header.FileLength = BT(header.FileLength);
	printf("FileLength=%d\n", header.FileLength);
	fread(&header.Version, sizeof(int), 1, ShpFile_fp);//读取Version
	printf("Version=%d\n", header.Version);
	fread(&header.ShapeType, sizeof(int), 1, ShpFile_fp);//读取ShapeType
	printf("ShapeType=%d\n", header.ShapeType);
	//文件头格式依次读取
	fread(&header.Xmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Ymin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Xmax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Ymax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Zmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Zmax, sizeof(double), 1, ShpFile_fp);
	fread(&header.Mmin, sizeof(double), 1, ShpFile_fp);
	fread(&header.Mmax, sizeof(double), 1, ShpFile_fp);
	//打印
	printf("Xmin=%lf\n", header.Xmin);
	printf("Ymin=%lf\n", header.Ymin);
	printf("Xmax=%lf\n", header.Xmax);
	printf("Ymax=%lf\n", header.Ymax);
	printf("Zmin=%lf\n", header.Zmin);
	printf("Zmin=%lf\n", header.Zmax);
	printf("Mmax=%lf\n", header.Mmin);
	printf("Mmax=%lf\n", header.Mmax);
}
//定义一个读取记录的函数
void  OnReadPolygonShp(FILE* ShpFile)
{	Point point;//先定义一个 Point类型的实例用于保存点
	int i, j;
	int RecordNumber;
	int ContentLength;
	int shapeType;
	double Box[4];
	int NumParts;
	int NumPoints;
	int *Parts;
	while ((fread(&RecordNumber, sizeof(int), 1, ShpFile) != 0))
	{	RecordNumber = BT(RecordNumber);//RecordNumber为大端需要BT转换
		abc.set_RecordNumber(RecordNumber);//存入实例中
		fread(&ContentLength, sizeof(int), 1, ShpFile);//按序读取
		ContentLength = BT(ContentLength);
		abc.set_ContentLength(ContentLength);
		fread(&shapeType, sizeof(int), 1, ShpFile);
		abc.set_ShapeType(shapeType);
		for (i = 0;i < 4;i++)
		{fread(Box + i, sizeof(double), 1, ShpFile);//范围
		}
		abc.set_Box(Box);
		fread(&NumParts, sizeof(int), 1, ShpFile);
		abc.set_NumParts(NumParts);
		Parts = new int[abc.NumParts];
		fread(&NumPoints, sizeof(int), 1, ShpFile);
		abc.set_NumPoints(NumPoints);
		for (i = 0;i < abc.NumParts;i++)//根据Part的个数记录
		{fread(&Parts[i], sizeof(int), 1, ShpFile);//部分的 开始点的索引
		}
		abc.set_Parts(Parts);
		int pointNum;//用来存储计算点个数
		for (i = 0;i < NumParts;i++)
		{   if (i != NumParts - 1)//如果不是倒数第二个
			pointNum = Parts[i + 1] - Parts[i];//用下一个Parts的地址 减去上一个地址 得出的就是点的地址个数
			else
				pointNum = NumPoints - Parts[i];
			double PointsX;
			double PointsY;
			for (j = 0;j < pointNum;j++)
			{	fread(&PointsX, sizeof(double), 1, ShpFile);
				fread(&PointsY, sizeof(double), 1, ShpFile);
				point.set_Point(PointsX, PointsY);//point属性赋值
				abc.set_Points(point);//对polygon属性赋值
			}
		}
		//一端段记录读取结束将添加到polygon容器中
			polygon.push_back(abc);
		//对polygon属性中的PO
			abc.vectorclose();
			}
}
//读取的值写入txt文本
void write(string filepath) {
	ofstream file;
	file.open(filepath, ios::out);
	file << "FileCode" ;
	file <<std::to_string(header.FileCode);//转换成字符串写入
	file<<"\n";
	file << "FileLength:";
	file << std::to_string(header.FileLength);
	file << "\n";
	file << "Version:";
	file << std::to_string(header.Version);
	file << "\n";
	file << "ShapeType:";
	file << std::to_string(header.ShapeType);
	file << "\n";
	file << "Xmin:";
	file << std::to_string(header.Xmin);
	file << "\n";
	file << "Ymin:";
	file << std::to_string(header.Ymin);
	file << "\n";
	file << "Xmax:";
	file << std::to_string(header.Xmax);
	file << "\n";
	file << "Ymax:";
	file << std::to_string(header.Ymax);
	file << "\n";
	file << "Zmin:";
	file << std::to_string(header.Zmin);
	file << "\n";
	file << "Zmax:";
	file << std::to_string(header.Zmax);
	file << "\n";
	file << "Mmin:";
	file << std::to_string(header.Mmin);
	file << "\n";
    file << "Mmax:";
	file << std::to_string(header.Mmax);
	file << "\n";
	//遍历polygon容器vector
	for (int i = 0;i < polygon.size();i++)
	{   file << "RecordNumber:";
		file << std::to_string(polygon[i].RecordNumber);
		file << "\n";
		file << "ContentLength:";
		file << std::to_string(polygon[i].ContentLength);
		file << "\n";
		file << "ShapeType:";
		file << std::to_string(polygon[i].ShapeType);
		file << "\n";
    	file << "NumParts:";
		file << std::to_string(polygon[i].NumParts);
		file << "\n";
		file << "NumPoints:";
		file << std::to_string(polygon[i].NumPoints);
		file << "\n";
		//遍历第i个ploygon的Point点 也可以 j<polygon.NumPoints
		for (int j=0;j < polygon[i].Points.size();j++)
		{	file<< "X:";
			cout << polygon[i].Points[j].X  ;
			std::to_string(polygon[i].Points[j].X);
			file << std::to_string(polygon[i].Points[j].X);
			file << "   Y:";
			cout << polygon[i].Points[j].Y << "\n";
			file << std::to_string(polygon[i].Points[j].Y);
			file << '\n';
		}
	}
}
 //将读取的数据存入新的.shp
void  writetoshp(string filepathh) {
    int zero =0;
	ofstream file;
	file.open(filepathh, ios::binary | ios::out);
	//将头文件的参数定义出来,并对大小端转换
	int code = BT(header.FileCode);
	int length = BT(header.FileLength);
	int version = BT(header.Version);
	int recordnumber;
	int contentlength;
	int shapetype;
	file.write((const char*)& code, sizeof(int));
	//5个unused
	for (int i = 0;i < 5;i++) {
		file.write((const char*)& zero, sizeof(int));
	}
	file.write((const char*)& length, sizeof(int));
	file.write((const char*)& header.Version, sizeof(int));
	file.write((const char*)& header.ShapeType, sizeof(int));
	file.write((const char*)& header.Xmin, sizeof(double));
	file.write((const char*)& header.Ymin, sizeof(double));
	file.write((const char*)& header.Xmax, sizeof(double));
	file.write((const char*)& header.Ymax, sizeof(double));
	file.write((const char*)& header.Zmin, sizeof(double));
	file.write((const char*)& header.Zmax, sizeof(double));
	file.write((const char*)& header.Mmin, sizeof(double));
	file.write((const char*)& header.Mmax, sizeof(double));
	//和写入txt步骤相同
	for (int i = 0;i < polygon.size();i++)
	{   recordnumber = BT(polygon[i].RecordNumber);
		contentlength = BT(polygon[i].ContentLength);
		file.write((const char*)& recordnumber, sizeof(int));
		file.write((const char*)& contentlength, sizeof(int));
		file.write((const char*)& polygon[i].ShapeType, sizeof(int));
		for (int j = 0;j < 4;j++)
		{
			file.write((const char*)& polygon[i].Box[j], sizeof(double));
		}
		file.write((const char*)& polygon[i].NumParts, sizeof(int));
		file.write((const char*)& polygon[i].NumPoints, sizeof(int));
		for (int j = 0;j < polygon[i].NumParts;j++)
		{	file.write((const char*)& polygon[i].Parts[j], sizeof(int));
		}
		for (int j = 0;j < polygon[i].NumPoints;j++)
		{	file.write((const char*)& polygon[i].Points[j].X, sizeof(double));
			file.write((const char*)& polygon[i].Points[j].Y, sizeof(double));
		}
	}
}

void main() {
	FILE* ShpFile_fp;
	fopen_s(&ShpFile_fp, "C:\\Users\\shitk\\Desktop\\ExtBkArea.shp", "rb");
    string file2path = "C:\\Users\\shitk\\Desktop\\new.shp";
	string filepath = "C:\\Users\\shitk\\Desktop\\polygon.txt";
	ReadFileHeard(ShpFile_fp);
	OnReadLineShp(ShpFile_fp);
	write(filepath);
	writetoshp(file2path);
	ConnectDatabase();
	create_table();
		//insert_header_data(header.FileCode, header.FileLength, header.Version,  header.ShapeType,header.Xmin,header.Ymin,header.Xmax,header.Ymax);
		//QueryDatabase();
	
	insert_header_data(header.FileCode, header.FileLength, header.Version, header.ShapeType, header.Xmin, header.Ymin, header.Xmax, header.Ymax);
	for (int i = 0;i < polygon.size();i++)
		{	insert_recordheader_data(polygon[i].RecordNumber, polygon[i].ContentLength, polygon[i].ShapeType, polygon[i].NumParts, polygon[i].NumPoints);

			for (int j = 0;j < polygon[i].Points.size();j++)
			{
				insert_pointrecord_data(polygon[i].Points[j].X, polygon[i].Points[j].Y, polygon[i].RecordNumber);
			}
	}
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值