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.

3014 lines
70 KiB
C++

1 month ago
#include "stdafx.h"
#include <stack>
#include <random>
#include "DrawOperator/XyIO.h"
#include "TinyXml/tinyxml.h"
#include "ActionDeleteItem.h"
#include "DrawOperator/Net.h"
#include "DrawOperator/LibraryManager.h"
#include "DrawOperator\FileUtility.h"
#include "DrawOperator/unordered_dense.h"
#include "DrawOperator\MergePDFFile.h"
#include "Util.h"
#include "Legend.h"
#include "UndecidedZone.h"
void XyDeSerialize(CXy* pXy, CArchive& ar);
extern "C" __declspec(dllexport)
void* XyCreate() {
CXy* pXy = new CXy;
AfxGetPublicFunction()->EnableJudgeRange(TRUE);
return pXy;
}
extern "C" __declspec(dllexport)
bool DestroyXy(CXy* pXy)
{
if (pXy != nullptr)
{
delete pXy;
pXy = nullptr;
}
return true;
}
extern "C" __declspec(dllexport)
bool XyOpenFile(CXy* pXy, LPCTSTR lpszFileName, bool realTimeDraw)
{
if (pXy != NULL) {
pXy->Clear();
}
else {
pXy = new CXy;
}
return pXy->OpenFile(lpszFileName, realTimeDraw);
//pXy->m_bRealTimeDraw = realTimeDraw;
//if (pXy->ReadOtherWithExtension(lpszFileName))
//{
// return TRUE;
//}
//CString path(lpszFileName);
//CString tempFileName = PreprocessFile(path);
//if (tempFileName.IsEmpty())
//{
// return FALSE;
//}
//CFile file;
//if (file.Open(tempFileName, CFile::modeRead))
//{
// CArchive ar(&file, CArchive::load);
// XyDeSerialize(pXy, ar);
// ar.Close();
// file.Close();
//}
//CFileStatus status;
//// ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD> tempFileName <20><> path <20><>ͬ<EFBFBD><CDAC>˵<EFBFBD><CBB5>ԭ<EFBFBD>ļ<EFBFBD>û<EFBFBD>м<EFBFBD><D0BC>ܣ<EFBFBD><DCA3><EFBFBD>ʱ<EFBFBD><CAB1> tempFileName <20><><EFBFBD><EFBFBD>ԭ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>
//if (CFile::GetStatus(tempFileName, status) && tempFileName != path)
//{
// CFile::Remove(tempFileName);
//}
//return TRUE;
}
extern "C" __declspec(dllexport)
bool XyDrawFile(CXy* pXy, HDC hdcMem, int left, int top, int width, int height)
{
CRect client;
client.left = left;
client.bottom = top;
client.top = height + top;
client.right = width + left;
CRect8 rect(1e100, -1e100, -1e100, 1e100);
if (pXy->GetCount() > 0)
{
pXy->GetRange(rect);
pXy->m_range = rect;
}
else {
return false;
}
CDC* pDC = CDC::FromHandle(hdcMem);
CXyDC m_xyDC;
m_xyDC.Create(pDC);
// m_xyDC.SetViewRect(client); 629612432
m_xyDC.Extend(rect, client, EXTEND_MODE_CENTER);
pXy->Draw(m_xyDC, false);
return true;
}
extern "C" __declspec(dllexport)
void XyEnableMeshPackage(CXy* pXy, bool enable) {
pXy->EnableMeshPackage(enable);
}
////////////////////////////////////////////////////////////////////////////////////////////
// <20><><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼƬ
////////////////////////////////////////////////////////////////////////////////////////////
extern "C" __declspec(dllexport)
HBITMAP GetBitmap(CXy* pXy, int width, int height, int inflate)
{
if (pXy == NULL)
return FALSE;
CDC dc; dc.CreateCompatibleDC(NULL);
CXyDC pDC;
pDC.Create(&dc, false);
//pDC.SetAntiAlias(true);
CSize sz(width, height);
CRect rt(0, 0, width, height);
int planes = dc.GetDeviceCaps(PLANES);
int bpp = dc.GetDeviceCaps(BITSPIXEL);
CBitmap* pBitmap, * pOldBitmap;
pBitmap = new CBitmap();
pBitmap->CreateBitmap(sz.cx, sz.cy, planes, bpp, NULL);
pOldBitmap = dc.SelectObject(pBitmap);
dc.FillSolidRect(0, 0, sz.cx, sz.cy, RGB(255, 255, 255));
CRect8 rect(1e100, -1e100, -1e100, 1e100);
if (pXy->GetCount() > 0)
{
pXy->GetRange(rect);
pXy->m_range = rect;
rt.InflateRect(-inflate, -inflate, -inflate, -inflate);
pDC.Extend(rect, rt, EXTEND_MODE_CENTER);
pDC.SetViewRect(rt);
pXy->Draw(pDC);
}
dc.SelectObject(pOldBitmap);
HBITMAP hBit = (HBITMAP)pBitmap->Detach();
pBitmap->DeleteObject();
dc.DeleteDC();
delete pBitmap;
return hBit;
}
extern "C" __declspec(dllexport)
bool GetMapSize(CXy* pXy, double& xMin, double& yMin, double& xMax, double& yMax)
{
CRect8 rect(1e100, -1e100, -1e100, 1e100);
pXy->GetRange(rect, false);
xMin = rect.left;
yMin = rect.bottom;
xMax = rect.right;
yMax = rect.top;
return true;
}
extern "C" __declspec(dllexport)
void DeleteHBITMAP(HBITMAP hBmp)
{
DeleteObject(hBmp);
}
void XyDeSerialize(CXy* pXy, CArchive& ar)
{
//CPublicFunction& pf = *AfxGetPublicFunction();
if (pXy == NULL) pXy = new CXy;
//BeginProgress(IDS_STRING_OpenFile);
CString name = ar.GetFile()->GetFileName();
name.MakeLower();
CSplitPath sp(name);
CString ext = sp.GetExtension();
//ar.m_pDocument = this; // set back-pointer in archive
if (ext == _T(".dfb") ||
ext == _T(".dft"))
{
pXy->m_version = pXy->DFB_ReadVersion(ar);
pXy->DFB_ReadEncrypt(ar, pXy->m_version);
if (pXy->IsEncrypted())
{
//if (!VerifyPassword(GetDraw()))
//{
// m_bCancelRead = TRUE;
// EndProgress();
// return;
//}
}
pXy->DFB_Serialize(ar, pXy->m_version);
}
else if (ext == ".dml" || ext == ".xml")
pXy->DML_Read2(*(ar.GetFile()));
else if (ext == ".pcg")
pXy->PCG_Read2(*(ar.GetFile()));
else
pXy->DFD_Read2(*(ar.GetFile()));
//// <20>ϲ<EFBFBD><CFB2><EFBFBD>Ե<EFBFBD><D4B5><EFBFBD><EFBFBD>
//m_pXy->CreateMeshPackage();
//EndProgress();
}
bool XySerialize(CXy* pXy, CArchive& ar, int docTypeID,int version=-1)
{
short ver = version;
switch (docTypeID)
{
default: //<2F><>ǰȱʡ<C8B1>
pXy->DFD_Write2(*(ar.GetFile()), ver, TRUE);
break;
case DF_FORMAT_DFT: //˫<><CBAB>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ʽ
case DF_FORMAT_BINARY: //˫<><CBAB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƹ<EFBFBD>ʽ
pXy->DFB_SerializeWrite(ar, ver, TRUE);
break;
case DF_FORMAT_DML:
pXy->DML_WriteAll(*(ar.GetFile()), ver, TRUE);
break;
case DF_FORMAT_PCG:
pXy->PCG_WriteAll(*(ar.GetFile()), 2, TRUE);
break;
case DF_FORMAT_OLD_ASCII: //<2F>ϰ汾-<2D><><EFBFBD><EFBFBD>д<EFBFBD>ϰ汾
//pXy->DFD_Write2(*(ar.GetFile()), 2004, TRUE);
pXy->DFD_Write2(*(ar.GetFile()), ver, TRUE);
break;
case DF_FORMAT_DXF:
//pxy->ToDxf(&GetDC(), *(ar.GetFile()));
//xy.ToDxf(&GetDC(), *(ar.GetFile()));
break;
case DF_FORMAT_CGM:
//pf.SetExportDPI(::GetPreferences().WorkaroundSave.m_nExportModeDPI, ::GetPreferences().WorkaroundSave.m_dExportDPI);
//pxy->ToCgm(&GetDC(), *(ar.GetFile()));
//xy.ToCgm(&GetDC(), *(ar.GetFile()));
break;
case DF_FORMAT_EPS:
//pf.SetExportDPI(::GetPreferences().WorkaroundSave.m_nExportModeDPI, ::GetPreferences().WorkaroundSave.m_dExportDPI);
//pxy->ToEps(&GetDC(), *(ar.GetFile()));
//xy.ToEps(&GetDC(), *(ar.GetFile()));
break;
case DF_FORMAT_PDF:
//pf.SetExportDPI(::GetPreferences().WorkaroundSave.m_nExportModeDPI, ::GetPreferences().WorkaroundSave.m_dExportDPI);
//pxy->ToPdf(&GetDC(), *(ar.GetFile()));
//xy.ToPdf(&GetDC(), *(ar.GetFile()));
break;
case DF_FORMAT_UMAP_ASC:
//pxy->ToUmap(&GetDC(), *(ar.GetFile()));
//xy.ToUmap(&GetDC(), *(ar.GetFile()));
break;
case DF_FORMAT_MAPGIS_W:
//pxy->ToMapGisAsc(&GetDC(), *(ar.GetFile()), FALSE);
//xy.ToMapGisAsc(&GetDC(), *(ar.GetFile()), FALSE);
break;
case DF_FORMAT_KML:
//pxy->ToKML(*(ar.GetFile()));
//xy.ToKML(*(ar.GetFile()));
break;
case DF_FORMAT_GEOMAP:
//pxy->ToGeoMap(&GetDC(), *(ar.GetFile()));
//xy.ToGeoMap(&GetDC(), *(ar.GetFile()));
break;
}
return TRUE;
}
// <20><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EBB5BD><EFBFBD>²<EFBFBD>
extern "C" __declspec(dllexport)
bool XyInsertDataBottom(CXy* pXy, BYTE* data, int dataLen, LPCTSTR newLayer) {
CXy* pxyMerge = new CXy;
bool bOpen = pxyMerge->ReadMemory(data, dataLen, 1);
if (bOpen == false) {
delete pxyMerge;
return FALSE;
}
// ȫ<><C8AB>װ<EFBFBD><D7B0>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
if (strlen(newLayer) != 0)
{
CString strNamePre = newLayer;
strNamePre += "\\";
CClassList* pClassList = pxyMerge->GetClassList();
for (POSITION posClass = pClassList->GetHeadPosition(); posClass != nullptr; pClassList->GetNext(posClass))
{
CLayerList* pLayerList = pClassList->GetAt(posClass);
for (POSITION posLayer = pLayerList->GetHeadPosition(); posLayer != nullptr; pLayerList->GetNext(posLayer))
{
CLayer* pLayer = pLayerList->GetAt(posLayer);
CString strNameOld = pLayer->GetName();
CString strNewName = strNamePre + strNameOld;
pLayer->SetName(strNewName);
}
}
}
if (!pxyMerge->GetProjection().IsEmpty() && !pXy->GetProjection().IsEmpty())
pxyMerge->ChangeToProjection(pXy->GetProjection());
CPositionList select;
pXy->MoveInBottom(pxyMerge, select);
delete pxyMerge;
return TRUE;
}
extern "C" __declspec(dllexport)
bool XyInsertFileAfter(CXy* pXy, LPCTSTR mergeFile, POSITION pos) {
CXy* pxyMerge = new CXy;
//pxyMerge->m_bRealTimeDraw = FALSE;
bool bOpen = XyOpenFile(pxyMerge, mergeFile, FALSE);
if (bOpen == false) {
delete pxyMerge;
return FALSE;
}
if (!pxyMerge->GetProjection().IsEmpty() && !pXy->GetProjection().IsEmpty())
pxyMerge->ChangeToProjection(pXy->GetProjection());
CPositionList select;
pXy->MoveIn(pxyMerge, select, pos, 0, 0, true, true);
delete pxyMerge;
return TRUE;
}
///<2F>ϲ<EFBFBD><CFB2><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>ļ<EFBFBD>
extern "C" __declspec(dllexport)
bool XyMerge(CXy* pXy, LPCTSTR mergeFile)
{
return XyInsertFileAfter(pXy, mergeFile, 0);
//CString name, strExt;
//CSplitPath sp(mergeFile);
//strExt = sp.GetExtension();
//strExt.MakeLower();
//
//CXy* pxyMerge = new CXy;
////pxyMerge->m_bRealTimeDraw = FALSE;
//bool bOpen = XyOpenFile(pxyMerge, mergeFile, FALSE);
//if (bOpen == false) {
// delete mergeFile;
// return FALSE;
//}
//if (!pxyMerge->GetProjection().IsEmpty() && !pXy->GetProjection().IsEmpty())
// pxyMerge->ChangeToProjection(pXy->GetProjection());
//CPositionList select;
//pXy->MoveIn(pxyMerge, select, 0, 0, 0, true, true);
//delete pxyMerge;
//return TRUE;
}
extern "C" __declspec(dllexport)
bool XySaveAs(CXy* pxy, LPCTSTR saveFile,int version=-1)
{
CString newName = saveFile;
if (newName.IsEmpty())
{
return false;
}
int docTypeID = 0;
CString ext = AfxGetPublicFunction()->GetSplitPath(newName, "ext");
if (ext.MakeLower() == _T(".xyz")) {
docTypeID = NFormatType::DF_FORMAT_XYZ;
}
else {
CDocType DocType;
docTypeID = DocType.GetIndexFromExt(AfxGetPublicFunction()->GetSplitPath(newName, "ext"));
docTypeID = DocType.GetIDFromIndex(docTypeID);
}
CFile file;
CFileException fileException;
if (file.Open(newName, CFile::modeCreate | CFile::modeWrite, &fileException))
{
if (version < 0) {
version = pxy->m_version;
}
CArchive ar(&file, CArchive::store);
XySerialize(pxy, ar, docTypeID, version);
ar.Close();
file.Close();
PostProcessFile(newName);
return TRUE;
}
return FALSE;
}
extern "C" __declspec(dllexport)
bool XyFindPointByName(CXy* pxy, LPCTSTR eleName, BYTE*& buffElement, int& buffLen)
{
CString strNameFind(eleName);
CPositionList posList;
POSITION posCur = pxy->GetValueList()->GetHeadPosition();
CString name;
COne* pOne;
while (true)
{
pxy->GetValueList()->GetNext(posCur);
if (posCur == 0) {
break;
}
pOne = pxy->GetAt(posCur);
if (pOne->GetType() == DOUBLEFOX_POINT) {
// if(pOne->IsCanEdit())
CPointNameEx* pPoint = (CPointNameEx*)pOne->GetValue();
if (pPoint->GetName() == strNameFind)
{
posList.AddTail(posCur);
}
}
}
if (posList.GetCount() == 0)
{
buffLen = 0;
return false;
}
return pxy->WriteMemory(buffElement, buffLen, posList, 3, 0);
}
extern "C" __declspec(dllexport)
bool XyFindPointByInfo(CXy* pxy, POSITION& posFind
, LPCTSTR elementName, double x, double y, LPCTSTR layerName)
{
posFind = 0;
if (pxy == 0)
{
return FALSE;
}
CString strLayerFind(layerName);
POSITION posCur = pxy->GetValueList()->GetHeadPosition();
COne* pOne;
CString name;
CString strlayer;
while (true)
{
pxy->GetValueList()->GetNext(posCur);
if (posCur == 0) {
break;
}
pOne = pxy->GetAt(posCur);
name = pOne->GetName();
if (elementName != name) {
continue;
}
strlayer = pOne->GetLayer()->GetName();
if (strLayerFind.GetLength() > 0 && strLayerFind != strlayer)
{
continue;
}
int eleType = pOne->GetType();
if (eleType == DOUBLEFOX_POINT
|| eleType == DOUBLEFOX_XYZ)
{
CPointNameEx* pPoint = (CPointNameEx*)pOne->GetValue();
if (abs(pPoint->x0 - x) > 1E-10 || abs(pPoint->y0 - y) > 1E-10) {
continue;
}
}
else if (eleType == DOUBLEFOX_TEXT)
{
CText* pPoint = (CText*)pOne->GetValue();
if (abs(pPoint->x0 - x) > 1E10 && abs(pPoint->y0 - y) > 1E10) {
continue;
}
}
posFind = posCur;
break;
}
if (posFind > 0) {
return true;
}
return false;
}
extern "C" __declspec(dllexport)
BOOL XyGetElementByPosition(CXy* pxy, BYTE*& buffElement, int& buffLen, POSITION elementPtr)
{
if (pxy == 0)
return FALSE;
COne* pOne = (COne*)(pxy->GetAt(elementPtr));
if (pOne == 0)
return FALSE;
if (pOne->GetType() == DOUBLEFOX_MESH) {
((CMesh*)(pOne->value))->WriteElementDML(buffElement, buffLen);
return TRUE;
}
else if (pOne->GetType() == DOUBLEFOX_TEXT) {
((CText*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else if (pOne->GetType() == DOUBLEFOX_ELLIPSE)
{
((CEllipse*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else if (pOne->GetType() == DOUBLEFOX_CIRCLE)
{
((CCircle*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else if (pOne->GetType() == DOUBLEFOX_ARC)
{
((CArc*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else if (pOne->GetType() == DOUBLEFOX_SCALERULER)
{
((CScaleRuler*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else if (pOne->GetType() == DOUBLEFOX_PROPORTION)
{
((CProportion*)(pOne->value))->color = pOne->color;
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
else
{
return pOne->WriteMemory(buffElement, 0, buffLen, 3);
}
}
extern "C" __declspec(dllexport)
BOOL XySetElement(CXy* pxy, BYTE* buffElement, int buffLen, POSITION elementPtr)
{
BOOL bEdited = FALSE;
POSITION pos;
pos = (POSITION)elementPtr;
COne* pOne = (COne*)(pxy->GetAt(pos));
if (pOne->GetType() == DOUBLEFOX_SECTION) {
((CSection*)(pOne->value))->ReadElementDML(buffElement, -1, buffLen);
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_MESH) {
CMesh* pMesh = (CMesh*)(pOne->value);
pMesh->m_bRealTimeDraw = false;
pMesh->ReadElementDML(buffElement, -1, buffLen);
pMesh->SetM(pMesh->m_pRuler->zmin, pMesh->m_pRuler->zmax);
pMesh->GetBitmap();
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_TEXT) {
pOne->ReadMemory(buffElement, -1, buffLen, 3);
CText* pText = (CText*)(pOne->value);
pText->color = pOne->color;
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_ELLIPSE)
{
pOne->ReadMemory(buffElement, 0, buffLen, 3);
((CEllipse*)(pOne->value))->color = pOne->color;
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_CIRCLE)
{
pOne->ReadMemory(buffElement, 0, buffLen, 3);
((CCircle*)(pOne->value))->color = pOne->color;
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_ARC)
{
pOne->ReadMemory(buffElement, 0, buffLen, 3);
((CArc*)(pOne->value))->color = pOne->color;
TRACE(_T("CArc Width:"), ((CArc*)(pOne->value))->m_dCurveWidth);
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_PROPORTION)
{
pOne->ReadMemory(buffElement, 0, buffLen, 3);
((CProportion*)(pOne->value))->color = pOne->color;
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_SCALERULER)
{
pOne->ReadMemory(buffElement, 0, buffLen, 3);
((CScaleRuler*)(pOne->value))->color = pOne->color;
bEdited = true;
}
else if (pOne->GetType() == DOUBLEFOX_CURVE)
{
CHowToViewCurve* pHWCOld = pOne->HowToViewCurve;
if (pHWCOld != NULL)
{
pHWCOld->Empty();
}
pOne->ReadMemory(buffElement, 0, buffLen, 3);
bEdited = true;
}
else
{
if (pOne->HowToViewCurve != NULL)
{
pOne->HowToViewCurve->Empty();
}
pOne->ReadMemory(buffElement, -1, buffLen, 3);
bEdited = true;
}
return bEdited;
}
extern "C" __declspec(dllexport)
int XyDeleteLayerElement(CXy* pxy, LPCTSTR layerName, BOOL childNode) {
CList<POSITION, POSITION> select;
if (childNode)
{
pxy->GetElement(layerName, select, TRUE);
}
else
{
pxy->GetElement(layerName, select, FALSE);
}
if (select.IsEmpty())
{
return 0;
}
POSITION pos = select.GetHeadPosition();
POSITION pt;
while (pos)
{
pt = select.GetNext(pos);
pxy->RemoveAt(pt);
}
return select.GetCount();
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param layerName ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD>ܣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>سɹ<EFBFBD>
*/
extern "C" __declspec(dllexport)
bool XyAddLayer(CXy* pXy, LPCTSTR layerName)
{
return pXy->FindAddLayer(layerName) != nullptr;
}
/**
* ͳ<EFBFBD>Ʊ߿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
int XyBorderCount(CXy* pXy)
{
CPositionList select;
return pXy->GetElement(DOUBLEFOX_GRID, select);
}
/**
* <EFBFBD><EFBFBD>ȡͼԪ<EFBFBD><EFBFBD>Χ
*
* \param pXy ͼ<EFBFBD><EFBFBD>
* \param pos ͼԪ<EFBFBD><EFBFBD> position
* \param left
* \param top
* \param right
* \param bottom
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
bool XyGetRange(CXy* pXy, POSITION pos, double* left, double* top, double* right, double* bottom)
{
if (pXy == nullptr || pos == nullptr)
{
return false;
}
COne* pOne = pXy->GetAt(pos);
if (pOne == nullptr)
{
return false;
}
CRect8 range = pOne->GetRect();
*left = range.left;
*right = range.right;
*top = range.top;
*bottom = range.bottom;
return true;
}
extern "C" __declspec(dllexport)
bool XyGetElementsRange(CXy* pXy, POSITION* posArray, int elementCount, double* minX, double* minY, double* maxX, double* maxY)
{
CRect8 range(1e100, -1e100, -1e100, 1e100);
for (int i = 0; i < elementCount; i++)
{
COne* pOne = pXy->GetAt(posArray[i]);
pOne->GetRange(range);
}
*minX = range.left;
*minY = range.bottom;
*maxX = range.right;
*maxY = range.top;
return true;
}
/**
* <EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϱ߿<EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void XyCreateDefaultBorder(CXy* pXy)
{
CLayer* pLayer = pXy->FindAddLayer("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
double nan = std::numeric_limits<double>::quiet_NaN();
double minX = nan;
double minY = nan;
double maxX = nan;
double maxY = nan;
CPtrList* value = pXy->GetValueList();
for (POSITION pos = value->GetHeadPosition(); pos != nullptr; value->GetNext(pos))
{
COne* pOne = (COne*)value->GetAt(pos);
if (!pOne->GetLayer()->IsViewAndEdit())
{
continue;
}
CRect8 range = pOne->GetRect();
if (std::isnan(minX))
{
minX = range.left;
maxX = range.right;
minY = range.bottom;
maxY = range.top;
}
if (range.left < minX)
{
minX = range.left;
}
if (range.right > maxX)
{
maxX = range.right;
}
if (range.top > maxY)
{
maxY = range.top;
}
if (range.bottom < minY)
{
minY = range.bottom;
}
}
TRACE("minX = %lf, maxX = %lf, minY = %lf, maxY = %lf\n", minX, maxX, minY, maxY);
CGridding* pGrid = new CGridding;
pGrid->m_step.SetSize(1000, 10);
//<2F>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>ݵ<EFBFBD>λ<EFBFBD><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>С
//step=GetDoc()->GetCurrentUnitScale();
pGrid->ScaleProperty(1000, 1000);
pGrid->SetRect(minX, minY, maxX, maxY);
pGrid->SetProjection(&(pXy->m_ExchangeXYZ));
pGrid->SetDisplayMode(CNet::showNull);
POSITION pos = pXy->AddElement(pGrid, DOUBLEFOX_GRID);
//pXy->SetElementColor(pos, color);
COne* pOne = pXy->GetAt(pos);
pOne->SetLayer(pLayer);
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɸѡ<EFBFBD><EFBFBD>ȡͼԪ
*
* \param pXy
* \param filter ɸѡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD><EFBFBD> "," <EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD> position <EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
BSTR XyGetElementByFilter(CXy* pXy, string filter)
{
return CString("").AllocSysString();
}
/**
* <EFBFBD>޸<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z <EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD>Χ
* \param pXy
* \param minZValue <EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD>С z ֵ
* \param maxZValue <EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵ
* \param mode 1 <EFBFBD><EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD>2 Ĩƽ
*/
extern "C" __declspec(dllexport)
void XyMapMeshValueRange(CXy* pXy, double minZValue, double maxZValue, int mode)
{
if (pXy == nullptr)
{
return;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵС<D6B5><D0A1> 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ 0
POSITION meshPos = pXy->FindFirstElement(DOUBLEFOX_MESH);
if (meshPos == nullptr)
{
return;
}
COne* pOne = pXy->GetAt(meshPos);
CMesh* pMesh = (CMesh*)(pOne->GetValue());
pMesh->SetM(minZValue, maxZValue);
CDimension3D* pDfg = pMesh->GetDfg();
long numx = 0;
long numy = 0;
pMesh->GetNumber(numx, numy);
int nIndexZ = 0;
if (pMesh->GetMeshType() == MESH_FXY && pDfg->n >= 3)
{
nIndexZ = pMesh->m_nFxyIndexZ;
}
const double invalidZ = -1E300;
#pragma omp parallel for
for (long x = 0; x < numx; x++)
{
for (long y = 0; y < numy; y++)
{
double z = pDfg->Value(x, y, nIndexZ);
if (IsUnvalidValue(z))
{
continue;
}
if (OutOfRange(z, minZValue, maxZValue))
{
if (mode == 1) // <20><>Ч<EFBFBD><D0A7>
{
pDfg->SetValue(x, y, invalidZ);
}
else
{
pDfg->SetValue(x, y, Flatten(z, minZValue, maxZValue));
}
}
}
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͵<EFBFBD>ֵ<EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD> z ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD>޳<EFBFBD>
* \param pXy
* \param outputName <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>
* \param layerName <EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ
* \param minValue <EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С z ֵ
* \param maxValue <EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵ
*/
extern "C" __declspec(dllexport)
void XyFilterContourLines(CXy* pXy, wchar_t* layerName, double minZValue, double maxZValue)
{
if (pXy == nullptr)
{
return;
}
// <20><> z <20><>С<EFBFBD><D0A1> minValue <20><> С<><D0A1> maxValue <20>ĵ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>޳<EFBFBD><DEB3><EFBFBD>
NBase::CPositionList selected;
std::vector<COne*> needRemoveCones;
CXyElementFilter filter;
filter.addLayer(CString(layerName), true)
.addType(DOUBLEFOX_CURVE);
pXy->GetElement(filter, selected);
for (POSITION pos = selected.GetHeadPosition(); pos != nullptr; selected.GetNext(pos))
{
POSITION pt = selected.GetAt(pos);
COne* pOne = pXy->GetAt(pt);
CCurveEx* pCurve = (CCurveEx*)pOne->GetValue();
if (pCurve->name == nullptr)
{
continue;
}
try
{
double z = std::stod(pCurve->name); // <20><><EFBFBD>ڵ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־<EFBFBD><D6BE><EFBFBD> z ֵ
if (z < minZValue || z > maxZValue)
{
needRemoveCones.push_back(pOne);
}
}
catch (std::invalid_argument&)
{
// FIXME: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD><D6A3>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD>
}
}
for (COne* pOne : needRemoveCones)
{
pXy->RemoveAt(pOne);
}
}
/**
* <EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ǰ<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õĽӿڣ<EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD>ڻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD>ٱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>»<EFBFBD>ȡ
*
* \param pXy
* \param left
* \param top
* \param right
* \param bottom
*/
extern "C" __declspec(dllexport)
void XyGetDisplay(CXy* pXy, double& left, double& top, double& right, double& bottom)
{
left = pXy->m_display.left;
top = pXy->m_display.top;
right = pXy->m_display.right;
bottom = pXy->m_display.bottom;
}
/**
* <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy
* \return <EFBFBD><EFBFBD><EFBFBD>
*/
short XyGetVersion(CXy* pXy)
{
return pXy->m_version;
}
static TiXmlElement* CreateSimpleElement(const std::string_view& key, double value)
{
TiXmlElement* childElement = new TiXmlElement(key.data());
std::string str = std::to_string(value);
childElement->LinkEndChild(new TiXmlText(str.data()));
return childElement;
}
static TiXmlElement* CreateSimpleElement(const std::string_view& key, const std::string_view& value)
{
TiXmlElement* childElement = new TiXmlElement(key.data());
childElement->LinkEndChild(new TiXmlText(value.data()));
return childElement;
}
struct MeshMetadata
{
int rows = 0;
int columns = 0;
double minX = 0.0f;
double maxX = 0.0f;
double minY = 0.0f;
double maxY = 0.0f;
double dx = 0.0f;
double dy = 0.0f;
double minZ = 0.0f;
double maxZ = 0.0f;
};
struct MeshPoint
{
double x = 0.0f;
double y = 0.0f;
double z = 0.0f;
};
static TiXmlElement* MetadataToXml(const MeshMetadata& metadata)
{
TiXmlElement* metadataElement = new TiXmlElement("Metadata");
metadataElement->LinkEndChild(CreateSimpleElement("Rows", metadata.rows));
metadataElement->LinkEndChild(CreateSimpleElement("Columns", metadata.columns));
metadataElement->LinkEndChild(CreateSimpleElement("MinX", metadata.minX));
metadataElement->LinkEndChild(CreateSimpleElement("MaxX", metadata.maxX));
metadataElement->LinkEndChild(CreateSimpleElement("MinY", metadata.minY));
metadataElement->LinkEndChild(CreateSimpleElement("MaxY", metadata.maxY));
metadataElement->LinkEndChild(CreateSimpleElement("DX", metadata.dx));
metadataElement->LinkEndChild(CreateSimpleElement("DY", metadata.dy));
return metadataElement;
}
static std::string GridToXml(const MeshMetadata& metadata, const std::vector<std::vector<MeshPoint>>& dataGrid)
{
TiXmlDocument doc;
TiXmlElement* rootElement = new TiXmlElement("Grid");
doc.LinkEndChild(rootElement);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA> <metadata>
TiXmlElement* metadataElement = MetadataToXml(metadata);
rootElement->LinkEndChild(metadataElement);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA>
TiXmlElement* coordinatesElement = new TiXmlElement("Coordinates");
rootElement->LinkEndChild(coordinatesElement);
std::vector<std::vector<TiXmlElement*>> dataElementGrid(metadata.rows, std::vector<TiXmlElement*>(metadata.columns));
#pragma omp parallel for
for (int i = 0; i < metadata.rows; i++)
{
for (int j = 0; j < metadata.columns; j++)
{
TiXmlElement* dataElement = new TiXmlElement("Data");
dataElement->SetAttribute("Row", i);
dataElement->SetAttribute("Col", j);
const auto& point = dataGrid[i][j];
dataElement->SetAttribute("X", point.x);
dataElement->SetAttribute("Y", point.y);
std::string value = std::to_string(point.z);
dataElement->LinkEndChild(new TiXmlText(value.c_str()));
dataElementGrid[i][j] = dataElement;
}
}
for (int i = 0; i < metadata.rows; i++)
{
for (int j = 0; j < metadata.columns; j++)
{
coordinatesElement->LinkEndChild(dataElementGrid[i][j]);
}
}
TiXmlPrinter printer;
doc.Accept(&printer);
std::string result = printer.CStr();
return result;
}
static CMesh* GetMesh(CXy* pXy)
{
if (pXy == nullptr)
{
return nullptr;
}
CPositionList select;
int nCount = pXy->GetElement(DOUBLEFOX_MESH, select);
if (nCount <= 0)
{
return nullptr;
}
return (CMesh*)pXy->GetAtValue(select.GetHead());
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ z ֵ
* \param pXy
* \param x x<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y y<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param z <EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD>z ֵ
* \param size x y z <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD>ȣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
bool XyGetMeshZValue(CXy* pXy, double* x, double* y, double* z, int size)
{
CMesh* pMesh = GetMesh(pXy);
if (pMesh == nullptr)
{
return false;
}
#pragma omp parallel for
for (int i = 0; i < size; i++)
{
z[i] = pMesh->GetValue(x[i], y[i]);
}
return true;
}
/// <summary>
/// ʧ<><CAA7>ʱ<EFBFBD><CAB1><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD><C7B4>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD>ù<EFBFBD><C3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>£<EFBFBD><C2A3><EFBFBD>ֹ C# <20>DZ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="metadata"><3E><><EFBFBD><EFBFBD>Ԫ<EFBFBD><D4AA><EFBFBD><EFBFBD></param>
/// <param name="x">x <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8></param>
/// <param name="y">y <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8></param>
/// <param name="z">z <20><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8></param>
static void SetMetadataToDefault(MeshMetadata& metadata, double** x, double** y, double** z)
{
metadata.rows = 0;
metadata.columns = 0;
*x = nullptr;
*y = nullptr;
*z = nullptr;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param metadata
* \param pDfg
*/
static void SetMeshMetadata(MeshMetadata& metadata, CDimension2D* pDfg)
{
metadata.rows = pDfg->num[0];
metadata.columns = pDfg->num[1];
metadata.dx = pDfg->delt[0];
metadata.dy = pDfg->delt[1];
metadata.minX = pDfg->xmin();
metadata.maxX = pDfg->xmax();
metadata.minY = pDfg->ymin();
metadata.maxY = pDfg->ymax();
metadata.minZ = pDfg->range[0];
metadata.maxZ = pDfg->range[1];
}
/**
* <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param pXy
* \return <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD> xml <EFBFBD><EFBFBD>ʽ
*/
extern "C" __declspec(dllexport)
bool XyGetMesh(CXy* pXy, MeshMetadata& metadata, double** x, double** y, double** z)
{
CMesh* pMesh = GetMesh(pXy);
if (pMesh == nullptr)
{
SetMetadataToDefault(metadata, x, y, z);
return false;
}
CDimension2D* pDfg = (CDimension3D*)(pMesh->GetMesh());
SetMeshMetadata(metadata, pDfg);
if (metadata.rows <= 0 || metadata.columns <= 0)
{
SetMetadataToDefault(metadata, x, y, z);
return false;
}
*x = new double[metadata.rows];
*y = new double[metadata.columns];
*z = new double[metadata.rows * metadata.columns];
for (int i = 0; i < metadata.rows; i++)
{
(*x)[i] = pDfg->x(i);
}
for (int i = 0; i < metadata.columns; i++)
{
(*y)[i] = pDfg->y(i);
}
#pragma omp parallel for
for (int i = 0; i < metadata.rows; i++)
{
for (int j = 0; j < metadata.columns; j++)
{
int index = i * metadata.columns + j;
(*z)[index] = pDfg->Value(i, j);
}
}
return true;
}
static std::unique_ptr<CMesh> CreateMesh(const MeshMetadata& metadata, const double* x, const double* y, const double* z)
{
auto pMesh = std::make_unique<CMesh>();
auto pDfg = std::make_unique<CDimension2D>();
int numx = metadata.rows;
int numy = metadata.columns;
double dx = metadata.dx;
double dy = metadata.dy;
double xmin = metadata.minX;
double ymin = metadata.minY;
double zmin = metadata.minZ;
double zmax = metadata.maxZ;
pDfg->Create(numx, numy, xmin, ymin, dx, dy);
pDfg->range[0] = zmin;
pDfg->range[1] = zmax;
for (int i = 0; i < numx; i++)
{
for (int j = 0; j < numy; j++)
{
pDfg->SetValue(i, j, z[i * numy + j]);
}
}
pMesh->SetMesh(pDfg.release(), MESH_DFG, FALSE);
pMesh->EnableUpdateRuler(TRUE);
pMesh->UpdateColorRuler();
return pMesh;
}
static void AddContourCurve(CXy* pXy, vector<CCurve*>* curves, vector<CString*>* layer)
{
for (size_t i = 0; i < curves->size(); i++)
{
CCurve* pCurve = curves->at(i);
if (pCurve == NULL) continue;
CCurveEx *ce = new CCurveEx(pCurve->num);
for (int i = 0; i < ce->num; i++)
{
ce->x[i] = pCurve->x[i];
ce->y[i] = pCurve->y[i];
ce->z[i] = pCurve->z[i];
}
ce->nPoint = pCurve->nPoint;
ce->GetLocation();
POSITION pos = NULL;
if (pCurve->name)
ce->SetName(pCurve->name);
pos = pXy->AddElement(ce, DOUBLEFOX_CURVE);
CString* pName = layer->at(i);
pXy->SetElementLayer(pos, *pName);
}
}
template <typename T>
void DeleteVectorData(std::vector<T *> &vec)
{
for (auto* p : vec) {
delete p;
}
vec.clear();
}
///
/// <20><><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
///
extern "C" __declspec(dllexport)
void XyMeshSmooth(CXy* pXy, POSITION posMesh, double smoothFactor, int smoothTimes = 2)
{
if (smoothFactor < 1e-10) {
return;
}
CMesh* pMeshNew = (CMesh*)(pXy->GetAt(posMesh)->value);
CGrid* pGrid = pMeshNew->GetMesh();
int numx = pGrid->xnum();
int numy = pGrid->ynum();
double dZMin = pGrid->range[0] - 0.001;
double dZMax = pGrid->range[1] + 0.001;
for (int i = 1; i < numx - 1; i++)
{
double dSigma = 0;
double dPtX = 0, dPtY = 0, dOtherX = 0, dOtherY = 0;
for (int j = 1; j < numy - 1; j++) {
double dValueCur = pGrid->Value(i, j);
if (dValueCur< dZMin || dValueCur>dZMax) {
continue;
}
//dPtX = ConvertX2Int(pGrid->x(i), ptOO);
//dPtY = ConvertY2Int(pGrid->y(j), ptOO);
dSigma = 0;
int nCount = 0;
double dValueTmp = pGrid->Value(i - 1, j - 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i - 1), ptOO), ConvertY2Int(pGrid->y(j - 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i, j - 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i), ptOO), ConvertY2Int(pGrid->y(j - 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i + 1, j - 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i + 1), ptOO), ConvertY2Int(pGrid->y(j - 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i - 1, j);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i - 1), ptOO), ConvertY2Int(pGrid->y(j), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i + 1, j);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i + 1), ptOO), ConvertY2Int(pGrid->y(j), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i - 1, j + 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i - 1), ptOO), ConvertY2Int(pGrid->y(j + 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i, j + 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i), ptOO), ConvertY2Int(pGrid->y(j + 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
dValueTmp = pGrid->Value(i + 1, j + 1);
if (dValueTmp >= dZMin && dValueTmp <= dZMax) {
//if (!intersectHelp->Intersects(LineSegment(Point64(dPtX, dPtY)
// , Point64(ConvertX2Int(pGrid->x(i + 1), ptOO), ConvertY2Int(pGrid->y(j + 1), ptOO)))))
//{
dSigma += dValueTmp;
nCount++;
//}
}
if (nCount == 0) {
return;
}
double dAverage = dSigma / nCount;
double dValueNew = (dValueCur + dAverage * smoothFactor) / (1.0 + smoothFactor);
pGrid->SetValue(i, j, dValueNew);
//TRACE("i:%d, j:%d, %lf\r\n", i, j, dValueNew);
}
}
}
extern "C" __declspec(dllexport)
void XyCreateContour(CXy* pXy, POSITION posMesh, double contourStep, int contourMarkStep)
{
CMesh* pMeshNew = (CMesh*)(pXy->GetAt(posMesh)->value);
CString strLayerMark = _T("Layer:\\<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>\\<EFBFBD><EFBFBD>ע");
CString strLayerOther = _T("Layer:\\<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>\\<EFBFBD>ޱ<EFBFBD>ע");
CString curLayerName = pXy->GetCurrentLayer()->GetPathName();
CLayer* pMarkLayer = pXy->FindLayer(strLayerMark);
CLayer* pOtherLayer = pXy->FindLayer(strLayerOther);
if (pMarkLayer == nullptr)
{
pMarkLayer = pXy->FindAddLayer(strLayerMark);
pMarkLayer->HowToViewCurve = new CHowToViewCurve();
pMarkLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE);
CCurveInName* pInName = new CCurveInName();
CRect8 rect = pMeshNew->GetRect();
pInName->text_h = rect.Width() / 300;
pInName->m_size.cx = pInName->text_h*0.06;
pInName->color = RGB(0, 0, 0);
pMarkLayer->HowToViewCurve->Add(pInName);
}
if (pOtherLayer == nullptr)
{
pOtherLayer = pXy->FindAddLayer(strLayerOther);
pOtherLayer->HowToViewCurve = new CHowToViewCurve();
pOtherLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE);
CCurveProperties* pview = new CCurveProperties();
pview->color = RGB(0, 0, 0);
pOtherLayer->HowToViewCurve->Add(pview);
}
std::vector<CCurve*> pCurves;
std::vector<CString*> pLayers;
CGrid* pDfg = pMeshNew->GetMesh();
pMeshNew->ContourCreate(&pCurves, &pLayers, contourStep, contourMarkStep,
strLayerMark, strLayerOther, pDfg->range[0], pDfg->range[1]);
AddContourCurve(pXy, &pCurves, &pLayers);
DeleteVectorData(pCurves);
DeleteVectorData(pLayers);
}
extern "C" __declspec(dllexport)
POSITION XyCreateMesh(CXy* pXy, LPCTSTR layerName, const float* values,
double xMin, double yMin, int xCount, int yCount, double stepX, double stepY,
double zMin, double zMax)
{
auto *pDfg = new CDimension2D();
pDfg->Create(xCount, yCount, xMin, yMin, stepX, stepY);
for (int i = 0; i < xCount; i++)
{
for (int j = 0; j < yCount; j++)
{
pDfg->SetValue(i, j, values[yCount*i + j]);
}
}
pDfg->range[0] = zMin;
pDfg->range[1] = zMax;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CMesh* pMeshNew = new CMesh(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CLayer* pLayer = pXy->FindAddLayer("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
POSITION posNew = pXy->AddElement(pMeshNew, DOUBLEFOX_MESH);
pXy->SetElementLayer(posNew, pLayer);
pMeshNew->SetMesh(pDfg, MESH_DFG, FALSE);
//pMeshNew->GetMesh();
//// <20><><EFBFBD>ɵ<EFBFBD>ֵ<EFBFBD><D6B5>
//CreateContourLines(pXy, pMeshNew, pDfg, contourStep, contourMarkStep);
pMeshNew->EnableUpdateRuler(TRUE);
pMeshNew->UpdateColorRuler();
return posNew;
}
/**
* ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD>
* \param layerName Ҫ<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param metadata <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x x <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y y <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param z <EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD> z ֵ
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true<EFBFBD><EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> false
*/
extern "C" __declspec(dllexport)
bool XyAddMesh(CXy* pXy, const LPCTSTR layerName, const MeshMetadata* metadata, const double* x, const double* y, const double* z)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (metadata == nullptr)
{
TRACE("metadata <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
auto pMesh = CreateMesh(*metadata, x, y, z);
CLayer* pLayer = pXy->FindAddLayer(layerName);
auto pOne = std::make_unique<COne>();
pOne->SetLayer(pLayer);
pOne->SetValueSafe(pMesh.release());
pXy->AddTailOne(pOne.release());
//pXy->SaveAsWithExtension("E:\\output.dfd");
return true;
}
extern "C" __declspec(dllexport)
bool XyGetMeshInfo(CXy* pXy, BYTE*& buffElement, int& buffLen)
{
CMesh* pMesh = GetMesh(pXy);
if (pMesh == nullptr)
{
return false;
}
pMesh->WriteElementDML(buffElement, buffLen);
return true;
}
extern "C" __declspec(dllexport)
bool XySetMeshInfo(CXy* pXy, LPCTSTR infoData)
{
CMesh* pMesh = GetMesh(pXy);
if (pMesh == nullptr)
{
return false;
}
pMesh->m_bRealTimeDraw = false;
CString strInforData(infoData);
CMemFile memFile((BYTE*)strInforData.GetString(), strInforData.GetLength());
pMesh->ReadElementDML(memFile, -1);
pMesh->SetM(pMesh->m_pRuler->zmin, pMesh->m_pRuler->zmax);
//pMesh->GetBitmap();
return true;
}
extern "C" __declspec(dllexport)
bool XyGetMeshData(CXy* pXy, double& xMin, double& yMin, int& xNum, int& yNum, double& xStep, double& yStep, double*& pValue, double &zMin, double& zMax)
{
CMesh* pMesh = GetMesh(pXy);
if (pMesh == nullptr)
{
return false;
}
CDimension2D* pDfg = (CDimension3D*)(pMesh->GetMesh());
xNum = pDfg->num[0];
yNum = pDfg->num[1];
xStep = pDfg->delt[0];
yStep = pDfg->delt[1];
xMin = pDfg->xmin();
yMin = pDfg->ymin();
pValue = pDfg->u;
zMin = pDfg->range[0];
zMax = pDfg->range[1];
return true;
}
/**
* ͼ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD> (<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼԪ<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD>)<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǽ<EFBFBD><EFBFBD><EFBFBD>ЩԪ<EFBFBD>طŵ<EFBFBD>ĩβ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy CXy ָ<EFBFBD><EFBFBD>
* \param layer ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param bWithSubLayer <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD>ͼԪһ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>
*
*/
extern "C" __declspec(dllexport)
void XyLayerElementOrderTop(CXy* pXy, const wchar_t* layer, bool bWithSubLayer)
{
assert(pXy != nullptr);
CPositionList list;
pXy->GetElement(CString(layer), list, bWithSubLayer, true);
for (POSITION p = list.GetHeadPosition(); p != nullptr; list.GetNext(p))
{
POSITION pos = list.GetAt(p);
if (pos != nullptr)
{
pos = pXy->MoveToFront(pos); // ֱ<>ӽ<EFBFBD><D3BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pos
if (pos != nullptr)
{
list.SetAt(p, pos);
}
}
}
}
/**
* ͼ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> (<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼԪ<EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD>)
*
* \param pXy CXy ָ<EFBFBD><EFBFBD>
* \param layer ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param bWithSubLayer <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD>ͼԪһ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>
*
*/
extern "C" __declspec(dllexport)
void XyLayerElementOrderBottom(CXy* pXy, const wchar_t* layer, bool bWithSubLayer)
{
assert(pXy != nullptr);
CPositionList list;
pXy->GetElement(CString(layer), list, bWithSubLayer, true);
for (POSITION p = list.GetTailPosition(); p != nullptr; list.GetPrev(p))
{
POSITION pos = list.GetAt(p);
if (pos != nullptr)
{
pos = pXy->MoveToBack(pos);
if (pos != nullptr)
{
list.SetAt(p, pos);
}
}
}
}
/**
* ͼ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
*
* \param pXy CXy ָ<EFBFBD><EFBFBD>
* \param layer ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param bWithSubLayer <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD>ͼԪһ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>
*
*/
extern "C" __declspec(dllexport)
void XyLayerElementOrderUp(CXy* pXy, const wchar_t* layer, bool bWithSubLayer)
{
assert(pXy != nullptr);
CPositionList list;
pXy->GetElement(CString(layer), list, bWithSubLayer, true);
for (POSITION p = list.GetTailPosition(); p != nullptr; list.GetPrev(p))
{
POSITION pos = list.GetAt(p);
if (pos != nullptr)
{
pos = pXy->MoveForward(pos);
if (pos != nullptr)
{
list.SetAt(p, pos);
}
}
}
}
/**
* ͼ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD>
*
* \param pXy CXy ָ<EFBFBD><EFBFBD>
* \param layer ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param bWithSubLayer <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD>ͼԪһ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD>
*
*/
extern "C" __declspec(dllexport)
void XyLayerElementOrderDown(CXy* pXy, const wchar_t* layer, bool bWithSubLayer)
{
assert(pXy != nullptr);
CPositionList list;
pXy->GetElement(CString(layer), list, bWithSubLayer, true);
for (POSITION p = list.GetHeadPosition(); p != nullptr; list.GetNext(p))
{
POSITION pos = list.GetAt(p);
if (pos != nullptr)
{
pos = pXy->MoveBackward(pos);
if (pos != nullptr)
{
list.SetAt(p, pos);
}
}
}
}
/**
* <EFBFBD>г<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> position
*
* \param pXy
* \return
*/
extern "C" __declspec(dllexport)
BSTR XyListAllElements(CXy* pXy)
{
assert(pXy != nullptr);
std::vector<CString> positions;
CPtrList* pValueList = pXy->GetValueList();
for (POSITION pos = pValueList->GetHeadPosition(); pos != nullptr; pValueList->GetNext(pos))
{
CString str;
str.Format("%I64d", pos);
positions.push_back(str);
}
return JoinStrings(positions, ",").AllocSysString();
}
static std::vector<CLayer*> GetAllLayers(const CXy& xy)
{
CXy& mutXy = const_cast<CXy&>(xy);
std::vector<CLayer*> result;
CClassList* pClassList = mutXy.GetClassList();
for (POSITION classPos = pClassList->GetHeadPosition(); classPos != nullptr; pClassList->GetNext(classPos))
{
CLayerList* pLayerList = pClassList->GetAt(classPos);
for (POSITION layerPos = pLayerList->GetHeadPosition(); layerPos != nullptr; pLayerList->GetNext((layerPos)))
{
result.push_back(pLayerList->GetAt(layerPos));
}
}
return result;
}
static void CopyHowtoViewCurve(const CLayer* pSourceLayer, CLayer* pTargetLayer)
{
if (pTargetLayer->HowToViewCurve != nullptr)
{
delete pTargetLayer->HowToViewCurve;
pTargetLayer->HowToViewCurve = nullptr;
}
if (pSourceLayer->HowToViewCurve != nullptr)
{
pTargetLayer->HowToViewCurve = new CHowToViewCurve();
*pTargetLayer->HowToViewCurve = *pSourceLayer->HowToViewCurve;
}
}
static void CopyHowtoViewPoint(const CLayer* pSourceLayer, CLayer* pTargetLayer)
{
if (pTargetLayer->HowToViewPoint != nullptr)
{
delete pTargetLayer->HowToViewPoint;
pTargetLayer->HowToViewPoint = nullptr;
}
if (pSourceLayer->HowToViewPoint != nullptr)
{
pTargetLayer->HowToViewPoint = new CHowToViewPoint();
*pTargetLayer->HowToViewPoint = *pSourceLayer->HowToViewPoint;
}
}
static void CopyMarkTo(CXy* pSourceXy, CXy* pTargetXy, const CString& symbolName)
{
assert(pSourceXy != nullptr);
assert(pTargetXy != nullptr);
if (symbolName.IsEmpty())
{
return;
}
CMapStringToPtrNoCase* pMarks = pSourceXy->GetMark();
void* pDraw;
if (pMarks->Lookup(symbolName, pDraw))
{
CXy* pOldSymbol = (CXy*)pDraw;
std::unique_ptr<CXy> pNewSymbol = std::make_unique<CXy>();
*pNewSymbol = *pOldSymbol;
pNewSymbol->m_strName = symbolName;
pTargetXy->AddMark(pNewSymbol.release(), true);
}
}
static void CopyHowtoViewMarkTo(CXy* pSourceXy, CHowToViewCurve* pHowToViewCurve, CHowToViewPoint* pHowToViewPoint, CXy* pTargetXy)
{
if (pHowToViewPoint != nullptr)
{
CopyMarkTo(pSourceXy, pTargetXy, pHowToViewPoint->MarkName);
}
if (pHowToViewCurve != nullptr)
{
for (int i = 0; i < pHowToViewCurve->GetCount(); i++)
{
CCurveView* pView = pHowToViewCurve->GetAt(i);
if (auto* pArrow = dynamic_cast<CCurveArrow*>(pView))
{
CopyMarkTo(pSourceXy, pTargetXy, pArrow->MarkName);
}
else if (auto* pScale = dynamic_cast<CCurveScale*>(pView))
{
CopyMarkTo(pSourceXy, pTargetXy, pScale->MarkName);
}
else if (auto* pTwoMark = dynamic_cast<CCurveTwoMark*>(pView))
{
CopyMarkTo(pSourceXy, pTargetXy, pTwoMark->MarkName);
}
else if (auto* pRgn = dynamic_cast<CCurveRgn*>(pView))
{
CopyMarkTo(pSourceXy, pTargetXy, pRgn->MarkName);
}
}
}
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy
* \param targetFilePath Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void XyApplyStyleToFile(CXy* pXy, LPCTSTR targetFilePath)
{
assert(pXy != nullptr);
std::unique_ptr<CXy> targetXy = std::make_unique<CXy>();
if (!XyOpenFile(targetXy.get(), targetFilePath, false))
{
return;
}
std::vector<CLayer*> layers = GetAllLayers(*pXy);
for (CLayer* pLayer : layers)
{
CString pathName = pLayer->GetPathName();
CLayer* pTargetLayer = targetXy->FindLayer(pathName, FALSE);
if (pTargetLayer == nullptr)
{
continue;
}
CopyHowtoViewCurve(pLayer, pTargetLayer);
CopyHowtoViewPoint(pLayer, pTargetLayer);
CopyHowtoViewMarkTo(pXy, pLayer->HowToViewCurve, pLayer->HowToViewPoint, targetXy.get());
}
targetXy->SaveAsWithExtension(targetFilePath);
}
static std::vector<CString> CollectValidLayerNames(CXy& xy, const std::vector<CString>& layerNames)
{
std::vector<CString> validNames;
for (const CString& name: layerNames)
{
CString layerPath = CLayerName(name).GetFullPathNameA();
for (CLayer* pLayer : CollectAllLayers(xy))
{
if (pLayer->GetPathName() == layerPath)
{
validNames.push_back(name);
break;
}
}
}
return validNames;
}
std::unique_ptr<COne> XyLegendCreate(CXy& xy, double x, double y, double width, int rows, LPCTSTR layerNames)
{
std::vector<CString> validNames = CollectValidLayerNames(xy, SplitString(layerNames, _T(",")));
if (validNames.size() == 0)
{
TRACE("û<EFBFBD>кϷ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>\n");
return nullptr;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
size_t columns = (validNames.size() + rows - 1) / rows;
Legend legend(xy, x, y, width, _T("ͼ<EFBFBD><EFBFBD>"), static_cast<int>(columns), validNames);
std::unique_ptr<CInsertBlock> pBlock = legend.Build();
std::unique_ptr<COne> pOne = std::make_unique<COne>();
CLayer* pLayer = xy.FindAddLayer(_T("ͼ<EFBFBD><EFBFBD>"));
pOne->SetValueSafe(pBlock.release());
pOne->SetLayer(pLayer);
return pOne;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*
* \param pXy Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
* \param x Ҫ<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ͼ<EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y Ҫ<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ͼ<EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param width ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param rows <EFBFBD><EFBFBD><EFBFBD>óɶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param layerNames <EFBFBD><EFBFBD>Щͼ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void XyLegendAdd(CXy* pXy, double x, double y, double width, int rows, LPCTSTR layerNames)
{
if (pXy == nullptr)
{
TRACE("pXy: ͼ<><CDBC><EFBFBD>ǿ<EFBFBD>ָ<EFBFBD><D6B8>\n");
return;
}
if (rows <= 0)
{
TRACE("rows: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С0\n");
return;
}
if (layerNames == nullptr)
{
TRACE("layerNames: ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ָ<EFBFBD><D6B8>\n");
return;
}
std::unique_ptr<COne> pOne = XyLegendCreate(*pXy, x, y, width, rows, layerNames);
if (pOne)
{
pXy->AddTailOne(pOne.release());
}
}
/**
*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>ռ<EFBFBD><EFBFBD>
*
* \param pXy Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
* \param x Ҫ<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ͼ<EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y Ҫ<EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>ͼ<EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param rows <EFBFBD><EFBFBD><EFBFBD>óɶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param layerNames <EFBFBD><EFBFBD>Щͼ<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
BSTR XyLegendMeasure(CXy* pXy, double width, int rows, LPCTSTR layerNames)
{
CString error;
error.Format("%lf,%lf", 0.0, 0.0);
if (pXy == nullptr)
{
TRACE("pXy: ͼ<><CDBC><EFBFBD>ǿ<EFBFBD>ָ<EFBFBD><D6B8>\n");
return error.AllocSysString();
}
if (rows <= 0)
{
TRACE("rows: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С0\n");
return error.AllocSysString();
}
if (layerNames == nullptr)
{
TRACE("layerNames: ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD>ָ<EFBFBD><D6B8>\n");
return error.AllocSysString();
}
std::vector<CString> validNames = CollectValidLayerNames(*pXy, SplitString(layerNames, _T(",")));
if (validNames.size() == 0)
{
TRACE("û<EFBFBD><EFBFBD><EFBFBD>κκϷ<EFBFBD>ͼ<EFBFBD><EFBFBD>\n");
return error.AllocSysString();
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>
size_t columns = (validNames.size() + rows - 1) / rows;
Legend legend(*pXy, 0, 0, width, _T("ͼ<EFBFBD><EFBFBD>"), static_cast<int>(columns), validNames);
std::unique_ptr<CInsertBlock> pBlock = legend.Build();
CString str;
str.Format("%lf,%lf", legend.GetWidth(), legend.GetHeight());
return str.AllocSysString();
}
/**
* <EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӱ߿<EFBFBD>
*
* \param pXy Ҫ<EFBFBD><EFBFBD><EFBFBD>ӱ߿<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
* \param layerName Ҫ<EFBFBD><EFBFBD><EFBFBD>߿<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param clip <EFBFBD>߿<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ն<EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
void XyBorderAdd(CXy* pXy, LPCTSTR layerName, double clip)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr");
return;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr");
return;
}
CRect8 range(1e100, -1e100, -1e100, 1e100);
pXy->GetRange(range);
double left = range.left - clip;
double top = range.top + clip;
double right = range.right + clip;
double bottom = range.bottom - clip;
std::unique_ptr<CGridding> pGridding = std::make_unique<CGridding>();
// <20><><EFBFBD>÷<EFBFBD>Χ
pGridding->SetRect(left, top, right, bottom);
pGridding->m_step.cx = std::trunc(abs(right - left) * (1.0 / 4.0)); // <20>Ȱѿ<C8B0><D1BF>߲<EFBFBD><DFB2><EFBFBD><EFBFBD>̶<EFBFBD><CCB6><EFBFBD>Ϊͼ<CEAA><CDBC><EFBFBD><EFBFBD><EFBFBD>ݵ<EFBFBD> 1/4
pGridding->m_step.cy = std::trunc(abs(top - bottom) * (1.0 / 4.0));
pGridding->m_szText.cx = 12;
pGridding->m_szText.cy = 30;
pGridding->m_nFlags = 29263;
pGridding->m_ptBase.x0 = 0.0;
pGridding->m_ptBase.y0 = 0.0;
pGridding->m_szCoefficient.cx = 1.0;
pGridding->m_szCoefficient.cy = 1.0;
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>߿<EFBFBD>
CFrame* pm = pGridding->GetOutFrame();
pm->thickness = 10;
pm->m_nFlags = 2309;
CLayer* pLayer = pXy->FindAddLayer(CString(layerName));
COne* pOne = new COne();
pOne->SetValueSafe(pGridding.release());
pOne->SetLayer(pLayer);
pOne->SetColor(RGB(0, 0, 0));
pXy->AddTailOne(pOne);
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> x1, y1 <EFBFBD><EFBFBD> x2, y2 <EFBFBD><EFBFBD><EFBFBD>м<EFBFBD><EFBFBD><EFBFBD>
*
* \param x1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param step <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return
*/
static std::vector<CPoint3D> GeneratePoints(double x1, double y1, double x2, double y2, double step)
{
double distance = CalcDistance(x1, y1, x2, y2);
int num_steps = static_cast<int>(distance / step);
double xIncrement = (x2 - x1) / distance * step;
double yIncrement = (y2 - y1) / distance * step;
std::vector<CPoint3D> result;
for (int i = 0; i < num_steps + 1; i++)
{
double x = x1 + i * xIncrement;
double y = y1 + i * yIncrement;
result.push_back({ x, y, -1e300 });
}
CPoint2D lastPoint = result[result.size() - 1];
if (lastPoint.x0 != x2 || lastPoint.y0 != y2)
{
result.push_back({ x2, y2, -1e300 });
}
return result;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵ
*
* \param mesh <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static std::unique_ptr<CCurveEx> CreateCurveFromMesh(const CMesh &mesh, double x1, double y1, double x2, double y2)
{
CMesh& mutMesh = const_cast<CMesh&>(mesh);
double dx = 0.0;
double dy = 0.0;
mutMesh.GetDelt(dx, dy);
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵ij<CCB5><C4B3>ȣ<EFBFBD><C8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̵ı߳<C4B1>
double step = min(dx, dy);
CRect8 range(1e300, -1e300, -1e300, 1e300);
mutMesh.GetRange(range);
std::vector<CPoint3D> points = GeneratePoints(x1, y1, x2, y2, step);
for (CPoint3D& point : points)
{
if (point.x0 >= range.left && point.x0 <= range.right &&
point.y0 >= range.bottom && point.y0 <= range.top)
{
point.z0 = mutMesh.GetValue(point.x0, point.y0);
}
}
auto pCurve = std::make_unique<CCurveEx>();
pCurve->Create(static_cast<int>(points.size()));
pCurve->nPoint = 3;
for (size_t i = 0; i < points.size(); i++)
{
pCurve->x[i] = points[i].x0;
pCurve->y[i] = points[i].y0;
pCurve->z[i] = points[i].z0;
}
return pCurve;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񴴽<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶ξ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵ
*
* \param xy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD>ʧ<EFBFBD>ܷ<EFBFBD><EFBFBD><EFBFBD> nullptr
*/
std::unique_ptr<CCurveEx> CreateCurveFromXyMesh(CXy& xy, double x1, double y1, double x2, double y2)
{
CPositionList select;
xy.GetElement(DOUBLEFOX_MESH, select);
CRect8 range1(min(x1, x2), max(y1, y2), max(x1, x2), min(y1, y2));
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
{
POSITION pt = select.GetAt(pos);
COne* pOne = xy.GetAt(pt);
CMesh* pMesh = pOne->GetValueSafe<CMesh>();
CRect8 range2(1e300, -1e300, -1e300, 1e300);
pMesh->GetRange(range2);
if (IsIntersecting(range1, range2))
{
return CreateCurveFromMesh(*pMesh, x1, y1, x2, y2);
}
}
return nullptr;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> z ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD> z ֵ
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
* \param layerName ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y1 <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> x <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y2 <EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> y <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return
*/
extern "C" __declspec(dllexport)
bool XyCreateCurveFillZ(CXy* pXy, LPCTSTR layerName, double x1, double y1, double x2, double y2)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ null\n");
return false;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
std::unique_ptr<CCurveEx> pCurve = CreateCurveFromXyMesh(*pXy, x1, y1, x2, y2);
if (!pCurve)
{
TRACE("δ<EFBFBD>ҵ<EFBFBD><EFBFBD>ռ<EFBFBD>λ<EFBFBD><EFBFBD>ƥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n");
return false;
}
CLayer* pLayer = pXy->FindAddLayer(CString(layerName));
auto pOne = std::make_unique<COne>();
pOne->SetLayer(pLayer);
pOne->SetValueSafe(pCurve.release());
pXy->AddTailOne(pOne.release());
return true;
}
static bool ExistLayerOrSubLayer(CXy& xy, const CString& layerName)
{
CString layerPath = CLayerName(layerName).GetFullPathNameA();
CClassList* pClassList = xy.GetClassList();
for (POSITION classListPos = pClassList->GetHeadPosition(); classListPos != nullptr; pClassList->GetNext(classListPos))
{
CLayerList* pLayerList = pClassList->GetAt(classListPos);
for (POSITION layerPos = pLayerList->GetHeadPosition(); layerPos != nullptr; pLayerList->GetNext(layerPos))
{
CLayer* pLayer = pLayerList->GetAt(layerPos);
CString currentPath = pLayer->GetPathName();
if (StartsWith(currentPath, layerPath))
{
return true;
}
}
}
return false;
}
static void MergeLayerElements(CXy& xy, CLayer& pSourceLayer, CLayer& pTargetLayer)
{
CPtrList* pValueList = xy.GetValueList();
for (POSITION pos = pValueList->GetHeadPosition(); pos != nullptr; pValueList->GetNext(pos))
{
COne* pOne = reinterpret_cast<COne*>(pValueList->GetAt(pos));
if (pOne != nullptr && pOne->GetLayer() == &pSourceLayer)
{
pOne->SetLayer(&pTargetLayer);
}
}
}
// <20>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD><CEAA>ͼ<EFBFBD><CDBC> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬһͼ<D2BB><CDBC>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD> true)
static bool IsSubLayerOf(const CString& layerPath, const CString& parentPath)
{
return StartsWith(layerPath, parentPath) &&
(layerPath.GetLength() == parentPath.GetLength() || layerPath[parentPath.GetLength()] == _T('\\'));
}
/**
* <EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param currentLayer <EFBFBD><EFBFBD>ǰͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param targetLayer Ŀ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return
*/
extern "C" __declspec(dllexport)
bool XyMoveLayerUnderTargetLayer(CXy* pXy, LPCTSTR layer , LPCTSTR parentLayer)
{
if (pXy == nullptr || layer == nullptr || parentLayer == nullptr)
{
TRACE("pXy layer parentLayer <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
// <20><><EFBFBD><EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD>ͼ<EFBFBD><EFBFBD><E3BCB0>ͼ<EFBFBD><EFBFBD><E3B6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!ExistLayerOrSubLayer(*pXy, layer))
{
TRACE("Ҫ<EFBFBD>ƶ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n", layer);
return false;
}
// <20><><EFBFBD><EFBFBD>2<EFBFBD><32>Ҫ<EFBFBD>ƶ<EFBFBD><C6B6><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD>Ӳ㶼<D3B2><E3B6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!ExistLayerOrSubLayer(*pXy, parentLayer))
{
TRACE("Ҫ<EFBFBD>ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD> %s <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\n", parentLayer);
return false;
}
CString sourceFullPath = CLayerName(layer).GetFullPathNameA();
CString parentFullPath = CLayerName(parentLayer).GetFullPathNameA();
int pos = CString(_T("Layer:")).GetLength();
std::vector<CString> layersToRemove;
CClassList* pClassList = pXy->GetClassList();
for (POSITION classListPos = pClassList->GetHeadPosition(); classListPos != nullptr; pClassList->GetNext(classListPos))
{
CLayerList* pLayerList = pClassList->GetAt(classListPos);
for (POSITION layerPos = pLayerList->GetHeadPosition(); layerPos != nullptr; pLayerList->GetNext(layerPos))
{
CLayer* pLayer = pLayerList->GetAt(layerPos);
CString layerPath = pLayer->GetPathName();
if (IsSubLayerOf(layerPath, sourceFullPath))
{
CString newLayerPath = parentFullPath + _T("\\") + CLayerName(layerPath).GetPathName();
CLayer* pFindLayer = pXy->FindLayer(newLayerPath);
if (pFindLayer == nullptr) // <20><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><EFBFBD><E3B2BB><EFBFBD>ڣ<EFBFBD>ֱ<EFBFBD>ӽ<EFBFBD><D3BD><EFBFBD>ǰͼ<C7B0><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
pLayer->SetName(CLayerName(newLayerPath).GetPathName());
}
else // <20><><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><EFBFBD><E3B1BE><EFBFBD>ʹ<EFBFBD><CDB4>ڣ<EFBFBD><DAA3>ϲ<EFBFBD>ͼ<EFBFBD><CDBC>Ԫ<EFBFBD><D4AA>
{
MergeLayerElements(*pXy, *pLayer, *pFindLayer);
layersToRemove.push_back(layerPath);
}
}
}
}
for (const CString& layerName : layersToRemove)
{
pXy->RemoveLayer(layerName);
}
return true;
}
/**
* <EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD> dfd <EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return dfd <EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
BSTR XyToDfdString(CXy* pXy)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr");
return CString().AllocSysString();
}
const UINT MB = 1024 * 1024;
const UINT blockSize = 16 * MB;
CMemFile memFile(blockSize);
int ret = pXy->DFD_Write(memFile, CUR_VERSION, true);
DWORD size = memFile.GetLength();
std::vector<BYTE> buffer(size + 1);
memFile.SeekToBegin();
memFile.Read(buffer.data(), size);
buffer[size] = '\0';
CString result{ buffer.data() };
return result.AllocSysString();
}
/**
* <EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD>
* \param filePath Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD>
* \param layerName Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return
*/
extern "C" __declspec(dllexport)
extern bool XySaveLayer(CXy* pXy, LPCTSTR filePath, LPCTSTR layerName)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (filePath == nullptr)
{
TRACE("filePath <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
CFileHelper fileHelper(filePath, CFile::modeCreate | CFile::modeWrite);
if (fileHelper.IsOpen())
{
CPositionList select;
pXy->GetElement(layerName, select, FALSE, TRUE);
pXy->DFD_Write(fileHelper.GetFile(), select);
return true;
}
return false;
}
extern "C" __declspec(dllexport)
bool XyAddPoint(CXy* pXy, LPCTSTR layerName, LPCTSTR pointName, double x, double y, double z)
{
if (pXy == nullptr || layerName == nullptr || pointName == nullptr)
{
TRACE("pXy layerName <20><> pointName <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
CLayer* pLayer = pXy->FindAddLayer(layerName);
if (pLayer == nullptr)
{
TRACE("<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>\n");
return false;
}
auto pPoint = std::make_unique<CPointNameEx>();
pPoint->SetName(pointName);
pPoint->x0 = x;
pPoint->y0 = y;
pPoint->z0 = z;
auto pOne = std::make_unique<COne>();
pOne->SetValueSafe(pPoint.release());
pOne->SetLayer(pLayer);
pXy->AddTailOne(pOne.release());
return true;
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \param pXy ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param layerName ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param curveName <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param x x<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param y y<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param z z<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param hasZ <EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD> z ֵ
* \param pointCount <EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>
*/
extern "C" __declspec(dllexport)
extern bool XyCurveAdd(CXy* pXy, LPCTSTR layerName, LPCTSTR curveName, const double* x, const double* y, const double* z, bool hasZ, int pointCount)
{
if (pXy == nullptr || layerName == nullptr || curveName == nullptr)
{
TRACE("pXy layerName <20><> curveName <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
CLayer* pLayer = pXy->FindAddLayer(layerName);
if (pLayer == nullptr)
{
TRACE("<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>\n");
return false;
}
auto pCurve = std::make_unique<CCurveEx>();
pCurve->SetName(curveName);
pCurve->Create(pointCount);
for (int i = 0; i < pointCount; i++)
{
pCurve->x[i] = x[i];
pCurve->y[i] = y[i];
if (hasZ)
{
pCurve->z[i] = z[i];
}
}
auto pOne = std::make_unique<COne>();
pOne->color = Color::Black;
pOne->SetValueSafe(pCurve.release());
pOne->SetLayer(pLayer);
pXy->AddTailOne(pOne.release());
return true;
}
/**
* <EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD>Ÿ<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD><EFBFBD>ǰͼ<EFBFBD><EFBFBD>
*
* \param pXy <EFBFBD><EFBFBD>ǰͼ<EFBFBD><EFBFBD>
* \param filePath <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \return
*/
extern "C" __declspec(dllexport)
bool XyMergeSymbol(CXy* pXy, LPCTSTR filePath)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (filePath == nullptr)
{
TRACE("filePath <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
CMapStringToPtrNoCase& mark = pXy->mark;
auto pTargetXy = std::make_unique<CXy>();
if (!pTargetXy->OpenFile(filePath, true))
{
return false;
}
CMapStringToPtrNoCase& targetMark = pTargetXy->mark;
POSITION pos = targetMark.GetStartPosition();
while (pos != nullptr)
{
CString name;
void* pDraw = nullptr;
targetMark.GetNextAssoc(pos, name, pDraw);
auto pCloneDraw = std::make_unique<CXy>();
*pCloneDraw = *(reinterpret_cast<CXy*>(pDraw));
pXy->AddMark(pCloneDraw.release(), TRUE);
}
return false;
}
static void CCurveColor(COne &one, COLORREF color)
{
auto property = std::make_unique<CCurvePropertiesEx>();
property->color = color;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀǰ<C4BF>Ǹ<EFBFBD><C7B8>ϲ<CFB2><E3B4A6><EFBFBD>õģ<C3B5>Ϊ<EFBFBD>˱<EFBFBD><CBB1><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫʱ<C9AB><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6A1B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӱ<EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SafeDelete(one.HowToViewCurve);
one.HowToViewCurve = new CHowToViewCurve();
one.HowToViewCurve->Add(property.release());
}
extern "C" __declspec(dllexport)
void XyClearLayerElementsEmbellish(CXy* pXy, LPCTSTR layerName, bool includeSubLayer)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return;
}
CPositionList select;
CXyElementFilter filter;
filter.addLayer(layerName, includeSubLayer);
pXy->GetElement(filter, select);
POSITION pos = select.GetHeadPosition();
while (pos != nullptr)
{
POSITION pt = select.GetNext(pos);
COne* pOne = pXy->GetAt(pt);
SafeDelete(pOne->HowToViewCurve);
SafeDelete(pOne->HowToViewPoint);
}
}
extern "C" __declspec(dllexport)
bool XyCurveMappingRandColor(CXy* pXy, LPCTSTR layerName, bool includeSubLayer)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
if (layerName == nullptr)
{
TRACE("layerName <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return false;
}
CPositionList select;
CXyElementFilter filter;
filter.addLayer(layerName, includeSubLayer);
filter.addType(DOUBLEFOX_CURVE);
pXy->GetElement(filter, select);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>̶<EFBFBD><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֣<EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>ÿ<EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɫ<EFBFBD><C9AB>һ<EFBFBD><D2BB>
std::mt19937 gen(123);
std::uniform_int_distribution<int> dist(30, 235); // 30 - 235<33><35><EFBFBD><EFBFBD>һЩ<D2BB>ӽ<EFBFBD><D3BD><EFBFBD>ɫ<EFBFBD>ͽӽ<CDBD><D3BD><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD>ų<EFBFBD><C5B3><EFBFBD>
// <20><>ɫ<EFBFBD><C9AB><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
const int MIN_BRIGHTNESS = 60;
const int MIN_SATURATION_DIFF = 50;
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
{
POSITION pt = select.GetAt(pos);
COne* pOne = pXy->GetAt(pt);
if (pOne != nullptr)
{
while (true)
{
int r = dist(gen);
int g = dist(gen);
int b = dist(gen);
// <20>ų<EFBFBD><C5B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double brightness = 0.299 * r + 0.587 * g + 0.114 * b;
if (brightness < 60)
{
continue;
}
#pragma push_macro("min")
#pragma push_macro("max")
#undef min
#undef max
// <20><><EFBFBD><EFBFBD>Ͷȣ<CDB6><C8A3><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><ECA3A9><EFBFBD><EFBFBD><EFBFBD>Ͷ<EFBFBD>̫<EFBFBD>͵<EFBFBD><CDB5>ų<EFBFBD><C5B3><EFBFBD>
int maxVal = std::max({r, g, b});
int minVal = std::min({r, g, b});
if (maxVal - minVal < MIN_SATURATION_DIFF)
{
continue;
}
#pragma pop_macro("min")
#pragma pop_macro("max")
CCurveColor(*pOne, RGB(r, g, b));
break;
}
}
}
return true;
}
struct ElementEmbellish
{
COne *pOne;
CString DML;
};
class ElementsEmbellishStack
{
public:
ElementsEmbellishStack() = default;
ElementsEmbellishStack(CXy* pXy)
{
m_pXy = pXy;
}
void Save(const CPositionList& positions)
{
StackItem item;
for (POSITION pos = positions.GetHeadPosition(); pos != nullptr; positions.GetNext(pos))
{
POSITION pt = positions.GetAt(pos);
COne* pOne = m_pXy->GetAt(pt);
CString text = GetOneEmbellish(pOne);
ElementEmbellish embellish{ pOne, text };
item.push_back(embellish);
}
m_stack.push(item);
}
void Restore()
{
if (m_stack.empty())
{
return;
}
StackItem& item = m_stack.top();
auto set = Cache();
for (auto &embellish : item)
{
if (set.contains(embellish.pOne))
{
SetOneEmbellish(embellish.pOne, embellish.DML);
}
}
m_stack.pop();
}
bool IsEmpty() const
{
return m_stack.empty();
}
private:
CString GetOneEmbellish(COne* pOne) const
{
CMemFile memFile;
pOne->WriteDML(memFile, CUR_VERSION, 0);
memFile.SeekToBegin();
auto length = memFile.GetLength();
int nChars = length / sizeof(TCHAR);
CString result;
result.GetBufferSetLength(nChars);
memFile.Read(result.GetBuffer(), length);
result.ReleaseBuffer();
memFile.Close();
return result;
}
void SetOneEmbellish(COne* pOne, const CString& text)
{
CMemFile memFile;
memFile.Write(text.GetString(), text.GetLength() * sizeof(TCHAR));
memFile.SeekToBegin();
auto pTempOne = std::make_unique<COne>();
pTempOne->ReadDML(memFile, CUR_VERSION);
memFile.Close();
SwapHowtoView(*pTempOne, *pOne);
}
ankerl::unordered_dense::set<COne*> Cache()
{
ankerl::unordered_dense::set<COne*> set;
CPtrList& values = *(m_pXy->GetValueList());
for (POSITION pos = values.GetHeadPosition(); pos != nullptr; values.GetNext(pos))
{
set.insert(reinterpret_cast<COne*>(values.GetAt(pos)));
}
return set;
}
using StackItem = std::vector<ElementEmbellish>;
using Stack = std::stack<StackItem>;
Stack m_stack;
CXy* m_pXy = nullptr;
};
/**
* ͳһ<EFBFBD><EFBFBD>Ԫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ι<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڶϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ʱԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
class ElementsEmbellishManager
{
public:
void SaveElementsEmbellish(CXy* pXy, CPositionList& select)
{
std::lock_guard locker(m_mutex);
auto it = m_map.find(pXy);
if (it == m_map.end())
{
m_map[pXy] = ElementsEmbellishStack(pXy);
}
m_map[pXy].Save(select);
}
void RestoreElementsEmbellish(CXy* pXy)
{
std::lock_guard locker(m_mutex);
auto it = m_map.find(pXy);
if (it != m_map.end())
{
it->second.Restore();
}
}
private:
ankerl::unordered_dense::map<CXy*, ElementsEmbellishStack> m_map;
std::mutex m_mutex;
};
extern "C" __declspec(dllexport)
void XySaveElementsEmbellish(CXy* pXy, LPCTSTR layerName, bool includeSubLayer)
{
CPositionList select;
pXy->GetElement(layerName, select, includeSubLayer);
GetInstace<ElementsEmbellishManager>().SaveElementsEmbellish(pXy, select);
}
extern "C" __declspec(dllexport)
void XyRestoreElementsEmbellish(CXy* pXy)
{
GetInstace<ElementsEmbellishManager>().RestoreElementsEmbellish(pXy);
}
/**
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>pdf<EFBFBD>ļ<EFBFBD>
*
* \param pXy <EFBFBD><EFBFBD>ǰͼ<EFBFBD><EFBFBD>
* \param filePath <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȫ·<EFBFBD><EFBFBD>
* \param paperType pdfֽ<EFBFBD>Ŵ<EFBFBD>С 0-A3 1-A4 2-A5 3-B4
* \param cType 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param dType 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ, 1Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \param left pdf<EFBFBD>߾<EFBFBD>
* \param right
* \param top
* \param bottom
* \return
*/
extern "C" __declspec(dllexport)
bool SavePDFFile(CXy* pXy, LPCTSTR filePath, int paperType, int cType, int dType, double left, double right, double top, double bottom, int num)
{
if (pXy == NULL || filePath == "")
return FALSE;
NBase::CRect8 rect(1e100, -1e100, -1e100, 1e100);
rect = pXy->m_range;
double dx = rect.Width();
double dy = rect.Height();
if (dx < 1e-20 || dy < 1e-20)
{
return FALSE;
}
NBase::CRect8 pRect(left, top, right, bottom);
CDC dc; dc.CreateCompatibleDC(NULL);
CRect rt(0, 0, dx, dy);
CXyDC *pDc = new CXyDC;
pDc->Extend(rect, rt, EXTEND_MODE_STRECH);
pDc->SetViewRect(rt);
pDc->SetPdfPrintState(TRUE);
pDc->SetFilePath(filePath);
pDc->Create(&dc, false);
pDc->SetPdfData(pXy, pRect, paperType, cType, dType, num);
pXy->Draw(*(CXyDC*)pDc, true);
pDc->CloseFile();
delete pDc;
return TRUE;
}
/**
* <EFBFBD>ϲ<EFBFBD>pdf<EFBFBD>ļ<EFBFBD>
*
* \param list <EFBFBD><EFBFBD>Ҫ<EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD>pdf<EFBFBD>ļ<EFBFBD>·<EFBFBD><EFBFBD>(<EFBFBD>ϲ<EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>˳<EFBFBD><EFBFBD>)
* \param count
* \param filePath <EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* \return
*/
extern "C" __declspec(dllexport)
bool MergePDFFiles(const wchar_t** list, int count, const wchar_t* filePath)
{
std::vector<CString> vListFile;
for (int i = 0; i < count; i++)
{
CString strFile(list[i]);
vListFile.push_back(strFile);
}
CString strOutFile(filePath);
std::unique_ptr<MergePDFFile> pMerge = std::make_unique<MergePDFFile>();
bool state = pMerge->MergePDFFiles(vListFile, strOutFile);
return state;
}
static std::shared_ptr<ElementFilter> createFilterFromXml(TiXmlElement* elem)
{
if (!elem)
{
return nullptr;
}
CString elemName = elem->Value();
if (elemName == _T("TrueFilter"))
{
return std::make_shared<TrueFilter>();
}
else if (elemName == _T("FalseFilter"))
{
return std::make_shared<FalseFilter>();
}
else if (elemName == _T("LayerFilter"))
{
CString layerName = CA2T(elem->Attribute("layerName"));
bool includeSublayer = false;
const char* includeAttr = elem->Attribute("includeSublayer");
if (includeAttr)
{
includeSublayer = (strcmp(includeAttr, "true") == 0);
}
return std::make_shared<LayerFilter>(layerName, includeSublayer);
}
else if (elemName == _T("TypeFilter"))
{
int type = -1;
elem->Attribute("type", &type);
return std::make_shared<TypeFilter>(type);
}
else if (elemName == _T("VisibilityFilter"))
{
bool includeHidden = false;
const char* attr = elem->Attribute("includeHidden");
if (attr)
{
includeHidden = (strcmp(attr, "true") == 0);
}
return std::make_shared<VisibilityFilter>(includeHidden);
}
else if (elemName == _T("EditableFilter"))
{
bool includeNotEditable = false;
const char* attr = elem->Attribute("includeNotEditable");
if (attr)
{
includeNotEditable = (strcmp(attr, "true") == 0);
}
return std::make_shared<EditableFilter>(includeNotEditable);
}
else if (elemName == _T("AndFilter"))
{
auto andFilter = std::make_shared<AndFilter>();
for (TiXmlElement* child = elem->FirstChildElement(); child; child = child->NextSiblingElement())
{
auto childFilter = createFilterFromXml(child);
if (childFilter)
{
andFilter->addFilter(childFilter);
}
}
return andFilter;
}
else if (elemName == _T("OrFilter"))
{
auto orFilter = std::make_shared<OrFilter>();
for (TiXmlElement* child = elem->FirstChildElement(); child; child = child->NextSiblingElement())
{
auto childFilter = createFilterFromXml(child);
if (childFilter)
{
orFilter->addFilter(childFilter);
}
}
return orFilter;
}
else if (elemName == _T("NotFilter"))
{
TiXmlElement* child = elem->FirstChildElement();
if (child)
{
auto childFilter = createFilterFromXml(child);
return std::make_shared<NotFilter>(childFilter);
}
else
{
// û<><C3BB><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϲ<EFBFBD>ƥ<EFBFBD><C6A5>
return std::make_shared<NotFilter>(nullptr);
}
}
else if (elemName == _T("NameFilter"))
{
CString nameValue;
bool ignoreCase = true;
bool matchAll = true;
// name
if (const char* attr = elem->Attribute("name"))
{
nameValue = CA2T(attr);
}
// ignoreCase
if (const char* attr = elem->Attribute("ignoreCase"))
{
ignoreCase = (strcmp(attr, "true") == 0);
}
// matchAll
if (const char* attr = elem->Attribute("matchAll"))
{
matchAll = (strcmp(attr, "true") == 0);
}
return std::make_shared<NameFilter>(nameValue, ignoreCase, matchAll);
}
return nullptr;
}
extern "C" __declspec(dllexport)
BSTR XyGetElement(CXy* pXy, LPCTSTR filterXml)
{
if (pXy == nullptr)
{
TRACE("pXy <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return CString().AllocSysString();
}
if (filterXml == nullptr)
{
TRACE("filterXml <20><><EFBFBD><EFBFBD>Ϊ nullptr\n");
return CString().AllocSysString();
}
TiXmlDocument doc;
doc.Parse(filterXml);
TiXmlElement* pRoot = doc.RootElement();
auto pFilter = createFilterFromXml(pRoot);
if (pFilter == nullptr)
{
TRACE("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> xml ʧ<><CAA7>\n");
return CString().AllocSysString();
}
CPositionList select;
pXy->GetElement(pFilter, select);
std::vector<CString> positions;
for (POSITION pos = select.GetHeadPosition(); pos != nullptr; select.GetNext(pos))
{
POSITION pt = select.GetAt(pos);
CString str;
str.Format("%I64d", pt);
positions.push_back(str);
}
return JoinStrings(positions, ",").AllocSysString();
}