最近施工上需要将平面坐标转化到地理坐标,叠加到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参反算施工坐标到地理坐标系