You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/GVision/FaultDensityLib/FltDensityAnalyzer.cpp

615 lines
12 KiB
C++

#include "stdafx.h"
#include "FltDensityAnalyzer.h"
#include <sstream>
#include <fstream>
#include <numeric>
CFltDensityAnalyzer::CFltDensityAnalyzer()
:m_fDx(1.0)
,m_fDy(1.0)
,m_aveDensity(0.0)
, m_minFltLength(0.0)
, m_bCalcWithRealArea(TRUE)
, m_fileLastOpen(_T(""))
{
}
CFltDensityAnalyzer::~CFltDensityAnalyzer()
{
ClearAll();
}
void CFltDensityAnalyzer::ClearAll(void)
{
ClearFlts();
ClearPolygons();
}
void CFltDensityAnalyzer::ClearPolygons(void)
{
for (int i = 0; i < m_cellPolygons.size(); i++)
delete m_cellPolygons[i];
m_cellPolygons.clear();
}
void CFltDensityAnalyzer::ClearFlts(void)
{
FLTITER i = m_flts.begin();
//for (; i != m_flts.end(); i ++)
// delete (*i);
m_flts.clear();
m_fltRects.clear();
}
void CFltDensityAnalyzer::SetOutputPaths(/*CString strDenAve,*/
CString strDenDist, CString strCellPolygons)
{
//m_strFltInput = strFlt;
//m_strBorder = strBd;
//m_strOutputDensityAverage = strDenAve;
m_strOuputDensityDistribution = strDenDist;
m_strOutputCellPolygons = strCellPolygons;
}
bool CFltDensityAnalyzer::ReadFltFile(CString strFlt)
{
m_strFltInput = strFlt;
m_fileLastOpen = strFlt;
m_fltMap.ClearAll();
if (0 == m_fltMap.ReadFile(m_strFltInput.GetBuffer()))
return false;
return true;
}
bool CFltDensityAnalyzer::ReadBorderFile(CString strBd)
{
m_strBorder = strBd;
return ReadBorder();
}
void CFltDensityAnalyzer::SetGrid(float dx, float dy)
{
if (dx < 1e-6)
dx = 1.0;
if (dy < 1e-6)
dy = 1.0;
m_fDx = dx;
m_fDy = dy;
}
//写出平均密度
bool CFltDensityAnalyzer::WriteAverageDensity(double dden, CString strAveDen)
{
FILE* fw = fopen((LPSTR)(LPCTSTR)strAveDen, "w");
if (0 == fw)
return false;
fprintf(fw, "断层平均密度: %.8f 条/平方公里\n", dden);
fclose(fw);
return true;
}
double CFltDensityAnalyzer::CalcDensity()
{
RemoveInvalidFlts();
CreateGridRects(); //生成网格单元矩形
CalcAverageDensity();
return m_aveDensity;
}
bool CFltDensityAnalyzer::Execute(void)
{
RemoveInvalidFlts();
CreateGridRects(); //生成网格单元矩形
//平均密度
/*double aveDensity = CalcAverageDensity();*/
CalcAverageDensity();
WriteAverageDensity(m_aveDensity, m_strOutputDensityAverage);
WriteGridFltsInfo();
WriteCellPolygons();
return true;
}
void CFltDensityAnalyzer::WriteGridFltsInfo(void)
{
std::ifstream file((LPSTR)(LPCTSTR)m_strOuputDensityDistribution);
if (file.good())
{
// 文件存在,关闭文件并删除文件
file.close();
std::remove(m_strOuputDensityDistribution);
}
FILE* fw = fopen((LPSTR)(LPCTSTR)m_strOuputDensityDistribution, "w");
if (0 == fw)
return ;
//fprintf(fw, "断层平均密度: %.6f 条/平方公里\n", dden);
GRect8 grt;
vector<GPline*> gflts;
int n = 0;
GPline testline;
GPoint3D cpt;
fprintf(fw, "中心点X,中心点Y,条数,面积(Km^2),密度(条/Km^2)\n");
double area = m_fDy*m_fDx / 1e6;
for (int i = 0; i < m_cellPolygons.size(); i++)
{
grt = m_grdRects[i];
//gflts.clear();
//n = GetRectFlts(grt, gflts);
////grt.GetCenter(cpt.x0,cpt.y0);
//cpt = m_grdCenters[i];
//fprintf(fw, "%.12g,%.12g,%d\n", cpt.x0, cpt.y0, n);
if (m_bCalcWithRealArea)
{
cpt = m_grdCenters[i];
n = m_grdFltNums[i];
area = m_cellPolygons[i]->Area() / 1e6;
fprintf(fw, "%.12g,%.12g,%d,%.6g,%.6g\n", cpt.x0, cpt.y0, n, area,
double(n) / area);
}
else
{
m_grdRects[i].GetCenter(cpt.x0,cpt.y0);
n = m_grdFltNums[i];
fprintf(fw, "%.12g,%.12g,%d,%.6g,%.6g\n", cpt.x0, cpt.y0, n, area,
double(n) / area);
}
}
fclose(fw);
}
void CFltDensityAnalyzer::WriteCellPolygons(void)
{
std::ifstream file((LPSTR)(LPCTSTR)m_strOutputCellPolygons);
if (file.good())
{
// 文件存在,关闭文件并删除文件
file.close();
std::remove(m_strOutputCellPolygons);
}
FILE* fw = fopen((LPSTR)(LPCTSTR)m_strOutputCellPolygons, "w");
if (0 == fw)
return;
CString str;
int n = 0;
GPline* pc = 0;
GPoint3D cpt;
double dFontHeight = m_fDx / 5.0;
double dFontWidth = dFontHeight*0.4;
fprintf(fw, "HowToViewPoint\n");
fprintf(fw, "Font 0 13 0 0 0 0 0 1 0 0 0 0 Times New Roman\n");
//fprintf(fw, "Text 200.0000 80.0000 0.0000 0.0000 0.0000 82\n");
fprintf(fw, "Text %lf %lf 0.0000 0.0000 0.0000 82\n", dFontHeight, dFontWidth);
fprintf(fw, "Color 0 0\n");
fprintf(fw, "FontZ 0 13 0 0 0 0 0 1 0 0 0 0 Times New Roman\n");
fprintf(fw, "TextZ 0.0000 0.0000 0.0000 0.0000 0.0000 100\n");
fprintf(fw, "ColorZ 0 0\n");
fprintf(fw, "Mark 0.0000 0.0000 0.0000\n");
fprintf(fw, "Mode 2048\n");
fprintf(fw, "\n");
fprintf(fw, "Layer M 0\n");
fprintf(fw, "Layer HowToViewPoint\n");
fprintf(fw, "HowToViewCurve\n");
fprintf(fw, "\n");
fprintf(fw, "HowToViewPoint\n");
fprintf(fw, "\n");
fprintf(fw, "State 10\n");
fprintf(fw, "Color 0\n");
fprintf(fw, "Layer M 0\n");
if (m_bCalcWithRealArea)
{
for (int i = 0; i < m_cellPolygons.size(); i++)
{
n = m_grdFltNums[i];
str.Format("%d", n);
pc = m_cellPolygons[i];
pc->SetName(str.GetBuffer());
cpt = m_grdCenters[i];
cpt.SetName(str.GetBuffer());
pc->Write(fw);
cpt.Write(fw);
fprintf(fw, "\n");
}
}
else
{
GRect8 grt;
GPline pc;
for (int i = 0; i < m_grdRects.size(); i++)
{
grt = m_grdRects[i];
n = m_grdFltNums[i];
str.Format("%d", n);
pc.FromRect(grt);
pc.SetName(str.GetBuffer());
grt.GetCenter(cpt.x0, cpt.y0);
cpt.SetName(str.GetBuffer());
pc.Write(fw);
cpt.Write(fw);
fprintf(fw, "\n");
}
}
fclose(fw);
}
float CFltDensityAnalyzer::GetFltLength(GPline * line)
{
double len = line->GetLength();
if (line->IsClosed(1e-6))
len /= 2.0;
return len;
}
int CFltDensityAnalyzer::GetLayers(vector<CString>& strlayers)
{
vector<string> veclayers;
m_fltMap.GetLayers(veclayers);
for (int i = 0; i < veclayers.size(); i++)
{
strlayers.push_back(veclayers[i].c_str());
}
return veclayers.size();
}
bool CFltDensityAnalyzer::CalcAverageDensity(void) //返回平均密度
{
int N = m_grdFltNums.size();
if (m_grdFltNums.empty())
return false;
double sum = 0.0;
for (int i = 0; i < m_cellPolygons.size(); i++)
{
sum += m_grdFltNums[i];
//sum += m_cellPolygons[i]->Area() * m_grdFltNums[i]/1e6;
}
double s = 0;
if (m_bCalcWithRealArea)
s = m_border.Area() / 1e6;
else
s = m_grdRects.size() * m_fDx*m_fDy / 1e6;
double d = sum / s;
m_aveDensity = d;
return true;
/*double s = m_border.Area();
if (s < 1e-8)
return 0;
double d = m_flts.size()*1e6/ s;
return d;*/
}
int CFltDensityAnalyzer::GetRectFlts(const GRect8& rect, vector<GPline*>& dstflts)
{
GPline rcur; rcur.FromRect(rect);
GRect8 fltrect;
FLTITER iter = m_flts.begin();
GPline* p1, *p2;
GPline* pFlt = 0;
int count = 0;
for (; iter != m_flts.end(); iter++)
{
p1 = &rcur;
p2 = *iter;
pFlt = p2;
fltrect = m_fltRects[p2];
if (!rect.IsIntersected(fltrect))
continue;
if (p2->IsClosed(1e-6) && p1->Area() < p2->Area())
std::swap(p1, p2);
if (0 == p1->IsInside(*p2))
continue;
dstflts.push_back(pFlt);
count++;
}
return count;
}
int CFltDensityAnalyzer::CreateGridRects(void)
{
m_grdRects.clear();
ClearPolygons();
m_grdCenters.clear();
m_grdFltNums.clear();
GRect8 bdrect = m_border.GetRect();
GRect8 rt;
int xnum = ceil(bdrect.Width() / m_fDx);
int ynum = ceil(bdrect.Height() / m_fDy);
double xx0 = bdrect.left;
double yy0 = bdrect.bottom;
double x0, y0;
int flag = 0;
double cx, cy;
GPline* pgnInside = 0;
GPline* pgnRect = 0;
m_grdRects.reserve(xnum*ynum);
vector<GPline*> relFlts;
for (int j = 0; j < ynum; j++)
{
y0 = yy0 + j*m_fDy;
for (int i = 0; i < xnum; i++)
{
x0 = xx0 + i * m_fDx;
rt.Create(x0, y0, m_fDx, m_fDy);
flag = m_border.IsInside(rt);
if(0 == flag) //不相交
continue;
if (1 == flag) //在边界内部
{
rt.GetCenter(cx, cy);
pgnRect = new GPline();
pgnRect->FromRect(rt);
//pgnRect.FromRect(rt);
m_grdRects.push_back(rt);
m_grdCenters.push_back(GPoint3D(cx, cy, 0));
m_cellPolygons.push_back(pgnRect);
}
else
{
pgnRect = new GPline();
pgnInside = new GPline();
pgnRect->FromRect(rt);
if (!m_border.GetIntersectedPolygon(*pgnRect, *pgnInside))
{
delete pgnRect;
delete pgnInside;
continue;
}
pgnInside->GetGravityCenter(cx, cy);
////begin test
//if(0 == pgnInside.IsInside(cx,cy))
//{
// FILE* fw = fopen("f:/rectandpgn.dfd", "w");
// pgnRect.Write(fw);
// pgnInside.Write(fw);
// GPoint3D ppt(cx, cy,0);
// ppt.Write(fw);
// fclose(fw);
// printf("");
//}
////end test
m_grdRects.push_back(rt);
m_grdCenters.push_back(GPoint3D(cx, cy, 0));
m_cellPolygons.push_back(pgnInside);
delete pgnRect;
}
relFlts.clear();
int nflt = GetRectFlts(rt, relFlts);
m_grdFltNums.push_back(nflt);
//if (2 == flag) //相交 ,判断中心点是否在边界内
//{
// rt.GetCenter(cx, cy);
// if (0 == m_border.IsInside(cx, cy))
// continue; //中心点不在边界内,跳过
//}
//m_grdRects.push_back(rt);
}
}
return m_grdRects.size();
}
//bool CFltDensityAnalyzer::ReadFltFile(void)
//{
//
//
//
// ////obsolete code
//
// //ClearFlts();
//
// //string line;
// //stringstream sstr;
//
// //ifstream ifs(m_strFltInput, fstream::in);
// //if (!ifs)
// // return false;
// //int idx = 0;
// //GRect8 rect;
// //int i = 0;
// //string str;
// //while (getline(ifs, line))
// //{
// // if (line.size() < 3)
// // continue;
// // idx = line.find("Pline");
// // if (idx < 0)
// // continue;
// // GPline* pc = new GPline();
// // i = line.find_first_of('.', 5);
// //
// // pc->SetName(line.substr(i + 1).c_str());
//
// // if (pc->ReadFile(ifs) < 2 || GetFltLength(pc) < m_minFltLength)
// // {
//
// // delete pc;
// // }
// // else
// // {
//
// // m_flts.push_back(pc);
// // rect = pc->GetRect();
// // m_fltRects[pc] = rect;
// // }
// //}
// //return true;
//
//}
bool CFltDensityAnalyzer::ReadFlts(CString strL, bool bIncludingSubLayers /*= true*/)
{
ClearFlts();
std::list<GBaseObj*> sels;
string strLayer(strL.GetBuffer());
if (strL.IsEmpty())
sels = m_fltMap.GetElements();
else
m_fltMap.GetElements(sels, strLayer, bIncludingSubLayers);
if (sels.empty())
return false;
GPline* pc = 0;
std::list<GBaseObj*>::iterator iter = sels.begin();
for (; iter != sels.end(); iter++)
{
if (eLine != (*iter)->GetType())
continue;
pc = (GPline*)(*iter);
if (GetFltLength(pc) < m_minFltLength)
continue;
m_flts.push_back(pc);
GRect8 rect = pc->GetRect();
m_fltRects[pc] = rect;
}
return true;
}
//读取指定层位边界
bool CFltDensityAnalyzer::ReadBorder(CString strL, bool bIncludingSubLayer)
{
m_border.Clear();
if (strL.IsEmpty())
return false;
std::list<GBaseObj*> sels;
string strLayer(strL.GetBuffer());
m_fltMap.GetElements(sels, strLayer, bIncludingSubLayer);
GPline* pc = 0;
std::list<GBaseObj*>::iterator iter = sels.begin();
for (; iter != sels.end(); iter++)
{
if (eLine != (*iter)->GetType())
continue;
m_border = *(GPline*)(*iter);
GRect8 trt = m_border.GetRect();
m_fltRects[&m_border] = trt;
break;
}
return true;
}
bool CFltDensityAnalyzer::ReadBorder(void)
{
string line;
std::ifstream ifs(m_strBorder, fstream::in);
if (!ifs)
return false;
int idx = 0;
GRect8 trt;
while (getline(ifs, line))
{
if (line.size() < 3)
continue;
idx = line.find("Pline");
if (idx < 0)
continue;
if (m_border.ReadFile(ifs) < 3)
continue;
trt = m_border.GetRect();
m_fltRects[&m_border] = trt;
return true;
}
return true;
}
int CFltDensityAnalyzer::IsInside(GPline & pc1, GPline & pc2)
{
GRect8 rt1, rt2;
rt1 = m_fltRects[&pc1];
rt2 = m_fltRects[&pc2];
//首先快速排斥
if (!rt1.IsIntersected(rt2))
return false;
return pc1.IsInside(pc2);
}
void CFltDensityAnalyzer::RemoveInvalidFlts(void)
{
std::list<GPline*>::iterator iter = m_flts.begin();
vector<GPline*> invalidplines;
for (iter = m_flts.begin(); iter != m_flts.end(); iter++)
{
if (0 == m_border.IsInside(*(*iter)))
invalidplines.push_back(*iter);
}
for (int i = 0; i < invalidplines.size(); i++)
{
m_flts.remove(invalidplines[i]);
//delete invalidplines[i];
}
}