CAD转化成SHP,并将平坐标做转化成地理坐标(通过控制点)

最近施工上需要将平面坐标转化到地理坐标,叠加到OSGearth看施工情况,就简单写了一个CAD转化成SHP并切换施工坐标为WGS84坐标的代码

#pragma once
#include 
#include "gdal/gdal.h"
#include "gdal/ogr_api.h"
#include "gdal/ogrsf_frmts.h"
#include 
#include 
#include "gdal/ogr_geometry.h"
class  GdalCommonUtil
{
public:
	static QList<QString> getDWGLayerinfo(QString path,QString drivername);
	static QString tranDWGtoShp(QString path,QString layername, QMap<int, double> params);
	static void csvToPoints(QString path, std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> &datas);
	static QMap<int, double> Canshu4(std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> datas);
	static bool isFileExist(QString fullFileName);
	static double toLanLot(QString str);
	static void pointsTocsv(QString path, std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> &datas);
	static std::pair<double, double> Canshu4(QMap<int, double> canshu4canshu4, std::pair<double, double> orgdata);
	static void addShpToView(QString shpfile);
 
};
#include "GdalCommonUtil.h"
#include 
#include "gdal/gdal_priv.h"
#include 
#include 
#include 
#include 
#include "Viewer/SceneManager.h"
QMap<int, double> GdalCommonUtil::Canshu4(std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> datas)
{
	return PramSCals::Canshu4(datas.second, datas.first, datas.first.size());
}
double GdalCommonUtil::toLanLot(QString str)
{
	auto infos = str.split(":");
	if (infos.size() >= 3)
	{
		QString tmp;
		for (int j = 0; j < infos[2].length(); j++)
		{
			if ((infos[2][j] >= '0' && infos[2][j] <= '9') || infos[2][j] == '.')
				tmp.append(infos[2][j]);
		}
		auto datas = tmp.toDouble() / 3600.0;
		return infos[0].toDouble() + (infos[1].toDouble() / 60.0) + datas;
	}
	return 0.0;
}
void GdalCommonUtil::pointsTocsv(QString path, std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> &datas)
{
	QDateTime time = QDateTime::currentDateTime();   //获取当前时间  
	QString armshp = QString("temp%1.csv").arg(time.toTime_t());

	QFile csvFile(armshp);
	if (csvFile.open(QIODevice::WriteOnly | QIODevice::Text))
	{
		for (int index = 0; index < datas.first.size(); index++)
		{
			QString str = QString("%1,%2,%3,%4,%5,%6\n").arg(QString::number(datas.first[index].getX(), 20, 8)).
				arg(QString::number(datas.first[index].getY(), 20, 8))
				.arg(QString::number(datas.first[index].getZ(), 20, 8))
				.arg(QString::number(datas.second[index].getX(), 20, 8))
				.arg(QString::number(datas.second[index].getY(), 20, 8))
				.arg(QString::number(datas.second[index].getZ(), 20, 8));
			csvFile.write(str.toStdString().c_str());
		}
		csvFile.close();
	}
}
void GdalCommonUtil::addShpToView(QString shpfile)
{
	QString uuid = SceneManager::getInstance()->addShp(shpfile);
	SceneManager::getInstance()->flyTo(uuid);
}
void GdalCommonUtil::csvToPoints(QString path,
	std::pair <std::vector<OGRPoint>, std::vector<OGRPoint>> &datas)
{
	datas.first.clear();
	datas.second.clear();
	QFile csvFile(path);
	QStringList csvList;
	csvList.clear();
	if (csvFile.open(QIODevice::ReadWrite)) //对csv文件进行读写操作
	{
		QTextStream stream(&csvFile);
		while (!stream.atEnd())
		{
			csvList.push_back(stream.readLine()); //保存到List当中
		}
		csvFile.close();
	}
	int i = 0;
	Q_FOREACH(QString str, csvList)   //遍历List
	{
		i = i + 1;
		QStringList valsplit = str.split(","); //分隔字符串
		if (i > 2)
		{
			//得到深度、声速、温度

			QString armlin = valsplit[3];
			QString armlat = valsplit[4];
			QString armheight = valsplit[5];

			OGRPoint armpoint;
			armpoint.setX(armlin.toDouble());
			armpoint.setY(armlat.toDouble());
			armpoint.setZ(armheight.toDouble());
			int zoneNo = (armlin.toDouble() / 100000) + 4508;
			datas.second.push_back(armpoint);
			QString orglin = valsplit[0];
			QString orglat = valsplit[1];
			QString orgheight = valsplit[2];
			OGRPoint orgpoint;
			orgpoint.setX(toLanLot(orglin));
			orgpoint.setY(toLanLot(orglat));
			orgpoint.setZ(orgheight.toDouble());
			OGRSpatialReference orgSRS, armSRS;
			orgSRS.importFromEPSG(4326);
			armSRS.importFromEPSG(zoneNo);
			OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&orgSRS,
				&armSRS);
			orgpoint.transform(poCT);
			datas.first.push_back(orgpoint);
		}
	}
}
std::pair<double, double> GdalCommonUtil::Canshu4(QMap<int, double> canshu4, std::pair<double, double> orgdata)
{
	std::pair<double, double> data;
	double p = canshu4[enum_scale];
	double A = canshu4[enum_rota];
	double X = canshu4[enum_dx];
	double Y = canshu4[enum_dy];
	/*X2 = X + (1 + m)*(cosaX1 - sinaY1)
		y2 = X + (1 + m)*(sinaX1 + cosaY1)*/
		/*D1中输入“ = (1 + p / 1000000)*(C1*COS(A) + D1 * SIN(A)) + X”
			F1中输入“ = (1 + p / 1000000)*(-C1 * SIN(A) + D1 * COS(A)) + Y”*/
			//data.first = (1 + p) * ((orgdata.first * qCos(A)) + (orgdata.second  * qSin(A))) + X;
			//data.second = (1 + p) * ((-orgdata.first * qSin(A)) + (orgdata.second  * qCos(A))) + Y;
	data.first = (1 + (p / 1000000)) * ((qCos(A) * orgdata.first) - (qSin(A) * orgdata.second)) + X;
	data.second = (1 + (p / 1000000)) * ((qCos(A) * orgdata.second) + (qSin(A) * orgdata.first)) + Y;
	return data;
	//return orgdata;

}
QString GdalCommonUtil::tranDWGtoShp(QString path, QString layername, QMap<int, double> params)
{
	GDALDataset *poORGDS = static_cast<GDALDataset *>(GDALOpenEx(
		path.toLocal8Bit().data(),
		((true || nullptr == nullptr) &&
			!false ? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR,
		nullptr, nullptr, nullptr));
	if (NULL == poORGDS)
	{
		return "";
	}
	auto orgLayer = poORGDS->GetLayerByName(layername.toLocal8Bit().data());
	if (NULL != orgLayer)
	{
		QDateTime time = QDateTime::currentDateTime();   //获取当前时间  
		QString armshp = QString("temp%1.shp").arg(time.toTime_t());
		QString armLayername = QString("temp%1").arg(time.toTime_t());
		auto poDriver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile");
		GDALDataset *poARMDS = poDriver->Create(armshp.toLocal8Bit().data(), 0, 0, 0, GDT_Unknown, NULL);
		if (NULL == poARMDS)
		{
			return "";
		}
		//获取原始图层坐标系
		auto * proj = poORGDS->GetGCPSpatialRef();
		OGRLayer * armlayer = NULL;
		if (NULL == proj)
		{
			OGRSpatialReference * newproj = new OGRSpatialReference();
			newproj->importFromEPSG(4326);
			armlayer = poARMDS->CreateLayer((const char*)armLayername.toLocal8Bit().data(), newproj, wkbUnknown, NULL);
		}
		OGRFeature * feature = NULL;
		while ((feature = orgLayer->GetNextFeature()) != NULL)
		{
			OGRFeature * newfeature = feature->Clone();
			auto newgeom = newfeature->GetGeometryRef()->clone();
			QString stringdata(newgeom->exportToJson());
			OGRSpatialReference orgSRS, armSRS;
			if (stringdata.contains("Point", Qt::CaseSensitive))
			{
				auto point = newgeom->toPoint();
				point->swapXY();
				std::pair<double, double> orgdata(point->getX(), point->getY());
				std::pair<double, double> newXY = Canshu4(params, orgdata);
				point->setX(newXY.first);
				point->setY(newXY.second);
				int zoneNo = (point->getX() / 100000) + 4508;
				orgSRS.importFromEPSG(zoneNo);
				armSRS.importFromEPSG(4326);
				OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&orgSRS,
					&armSRS);
				point->transform(poCT);
				CPLFree(poCT);
				point->swapXY();
				newfeature->SetGeometry(point);
			}
			if (stringdata.contains("LineString", Qt::CaseSensitive))
			{
				auto linestring = newgeom->toLineString();
				linestring->swapXY();
				for (int i = 0; i < linestring->getNumPoints(); i++)
				{
					std::pair<double, double> orgdata(linestring->getX(i), linestring->getY(i));
					std::pair<double, double> newXY = Canshu4(params, orgdata);
					linestring->setPoint(i, newXY.first, newXY.second);
				}
				int zoneNo = (linestring->getX(0) / 100000) + 4508;
				orgSRS.importFromEPSG(zoneNo);
				armSRS.importFromEPSG(4326);
				OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&orgSRS,
					&armSRS);
				linestring->transform(poCT);
				CPLFree(poCT);
				linestring->swapXY();
				newfeature->SetGeometry(linestring);
			}

			if (stringdata.contains("Polygon", Qt::CaseSensitive))
			{
				auto polygon = newgeom->toPolygon();
				polygon->swapXY();
				auto exteriorRing = polygon->getExteriorRing();
				exteriorRing = polygon->getExteriorRing();
				for (int i = 0; i < exteriorRing->getNumPoints(); i++)
				{
					std::pair<double, double> orgdata(exteriorRing->getX(i), exteriorRing->getY(i));
					std::pair<double, double> newXY = Canshu4(params, orgdata);
					exteriorRing->setPoint(i, newXY.first, newXY.second);
				}
				int zoneNo = (exteriorRing->getX(0) / 100000) + 4508;
				orgSRS.importFromEPSG(zoneNo);
				armSRS.importFromEPSG(4326);
				OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation(&orgSRS,
					&armSRS);
				polygon->transform(poCT);
				CPLFree(poCT);
				polygon->swapXY();
				newfeature->SetGeometry(polygon);
			}
			armlayer->CreateFeature(newfeature);
			//delete newfeature->GetGeometryRef();
			OGRFeature::DestroyFeature(newfeature);
		}
		if (NULL != poARMDS)
		{
			GDALClose(poARMDS);
			//poARMDS = NULL;
		}
		if (NULL != poORGDS)
		{
			GDALClose(poORGDS);
			//poORGDS = NULL;
		}
		addShpToView(armshp);
		return armshp;
	}
	return "";
}
QList<QString> GdalCommonUtil::getDWGLayerinfo(QString path, QString drivername)
{

	GDALDataset *poDS = static_cast<GDALDataset *>(GDALOpenEx(
		path.toLocal8Bit().data(),
		((true || nullptr == nullptr) &&
			!false ? GDAL_OF_READONLY : GDAL_OF_UPDATE) | GDAL_OF_VECTOR,
		nullptr, nullptr, nullptr));
	QList<QString> params;
	if (NULL == poDS)
	{
		return params;
	}
	int layercount = poDS->GetLayerCount();

	for (int iLayer = 0; iLayer < layercount; iLayer++)
	{
		OGRLayer *poLayer = poDS->GetLayer(iLayer);
		if (NULL != poLayer)
		{
			params.push_back(poLayer->GetName());
		}
	}
	if (NULL != poDS)
	{
		GDALClose(poDS);
		poDS = NULL;
	}
	return params;
}
bool GdalCommonUtil::isFileExist(QString fullFileName)
{
	QFileInfo fileInfo(fullFileName);
	if (fileInfo.isFile())
	{
		return true;
	}
	return false;
}
std::pair<double, double> GdalCommonUtil::Canshu4(QMap<int, double> canshu4, std::pair<double, double> orgdata)
{
	std::pair<double, double> data;
	double p = canshu4[enum_scale];
	double A = canshu4[enum_rota];
	double X = canshu4[enum_dx];
	double Y = canshu4[enum_dy];
	/*X2 = X + (1 + m)*(cosaX1 - sinaY1)
		y2 = X + (1 + m)*(sinaX1 + cosaY1)*/
		/*D1中输入“ = (1 + p / 1000000)*(C1*COS(A) + D1 * SIN(A)) + X”
			F1中输入“ = (1 + p / 1000000)*(-C1 * SIN(A) + D1 * COS(A)) + Y”*/
			//data.first = (1 + p) * ((orgdata.first * qCos(A)) + (orgdata.second  * qSin(A))) + X;
			//data.second = (1 + p) * ((-orgdata.first * qSin(A)) + (orgdata.second  * qCos(A))) + Y;
	data.first = (1 + (p / 1000000)) * ((qCos(A) * orgdata.first) - (qSin(A) * orgdata.second)) + X;
	data.second = (1 + (p / 1000000)) * ((qCos(A) * orgdata.second) + (qSin(A) * orgdata.first)) + Y;
	return data;
	//return orgdata;

}

通过4参反算施工坐标到地理坐标系

你可能感兴趣的:(CAD转化成SHP,并将平坐标做转化成地理坐标(通过控制点))