#pragma once
class GeoPolygonToolPrivate;
class GeoPolygonTool
{
public:
GeoPolygonTool();
~GeoPolygonTool();
void addEnvelopData2D(double** data, int count);
//0:ExteriorRing 1~n:InteriorRings
char* genUnionEnvelopJson();
private:
GeoPolygonToolPrivate* _pri;
};
#include "GeoPolygonTool.h"
#include "ogr/ogr_geometry.h"
#include <string>
#if WIN32
#include <windows.h>
#endif
class GeoPolygonToolPrivate
{
public:
GeoPolygonToolPrivate(){
pMultiPolygon = (OGRMultiPolygon*)OGRGeometryFactory::createGeometry(wkbMultiPolygon);
}
~GeoPolygonToolPrivate() {
OGRGeometryFactory::destroyGeometry(pMultiPolygon);
}
void addEnvelopData2D(double** data, int count);
char* genUnionEnvelopJson();
OGRMultiPolygon* pMultiPolygon;
};
void GeoPolygonToolPrivate::addEnvelopData2D(double** data,int count)
{
if (data == NULL) return;
OGRGeometry* pGeom_1 = NULL;
std::string sWKT = "POLYGON ((";
for (int i = 0; i < count;i++)
{
sWKT.append(std::to_string(data[i][0]));
sWKT.append(" ");
sWKT.append(std::to_string(data[i][1]));
sWKT.append(", ");
}
sWKT.append(std::to_string(data[0][0]));
sWKT.append(" ");
sWKT.append(std::to_string(data[0][1]));
sWKT.append("))");
char* szWKT_1 = (char*)sWKT.c_str();
OGRGeometryFactory::createFromWkt(&szWKT_1, NULL, &pGeom_1);
if (pGeom_1) {
pMultiPolygon->addGeometryDirectly(pGeom_1);
}
}
char* GeoPolygonToolPrivate::genUnionEnvelopJson()
{
char* json_out = NULL;
//用Buffer替代Union,缓冲距离设置为0
OGRGeometry* pUnion = pMultiPolygon->Buffer(0);
if (pUnion) {
json_out = pUnion->exportToJson();
#if WIN32 & _DEBUG
OutputDebugString(json_out);
#endif
}
return json_out;
}
//
GeoPolygonTool::GeoPolygonTool()
{
_pri = new GeoPolygonToolPrivate();
}
GeoPolygonTool::~GeoPolygonTool()
{
delete _pri;
_pri = NULL;
}
void GeoPolygonTool::addEnvelopData2D(double** data, int count)
{
_pri->addEnvelopData2D(data,count);
}
char* GeoPolygonTool::genUnionEnvelopJson()
{
return _pri->genUnionEnvelopJson();
}
#include "GeoPolygonTool.h"
QPolygonF coordinatesPolygon(const QJsonArray& jsonArrs)
{
double dx, dy;
QPolygonF polygonOut;
for (auto itor = jsonArrs.begin(); itor != jsonArrs.end(); ++itor)
{
QJsonArray jsonDatas = (*itor).toArray();
QPolygonF polygon;
for (auto jtor = jsonDatas.begin(); jtor != jsonDatas.end(); ++jtor)
{
float lon = (*jtor).toArray().first().toDouble();
float lat = (*jtor).toArray().last().toDouble();
polygon << QPointF(dx, dy);
}
if (polygonOut.isEmpty()) {
polygonOut = polygon;
}
else {
polygonOut = polygonOut.subtracted(polygon);
}
}
return polygonOut;
}
void createUnitedPolygon(std::vector<double**> envelop2dDatas, QVector<QPolygonF>& polygonUited)
{
GeoPolygonTool geoTool;
for (int i = 0; i < envelop2dDatas.size();i++)
{
geoTool.addEnvelopData2D(envelop2dDatas.at(i), 360);
}
char* json_out = geoTool.genUnionEnvelopJson();
if (json_out)
{
double dx, dy;
QJson::Parser p;
QJsonObject jsonObj = p.parse(json_out).toJsonObject();
QJsonArray jsonArrs = jsonObj.value("coordinates").toArray();
if (jsonObj.value("type") == "MultiPolygon") {
//MultiPolygon
for (auto itor = jsonArrs.begin(); itor != jsonArrs.end(); ++itor)
{
polygonUited.push_back(coordinatesPolygon((*itor).toArray()));
}
}
else {
polygonUited.push_back(coordinatesPolygon(jsonArrs));
}
}
}