📄 ydtcommands.cpp
字号:
//指定前点,后点
AcGePoint3d m_GreaterMilePt,m_LessMilePt;
if (ads_getpoint(NULL,"\n请指定线段终点:",asDblArray(ptEnd))!=RTNORM)
{
acedPrompt("\n未指定里程标注正向");
return;
}
//指定起点里程
if(acedGetReal("\n请输入起点里程: ",&m_dStartMile)!=RTNORM)
{
acedPrompt("\n未指定起点里程");
}
ads_printf("\n当前标注比例:[1:%d]",int(1000.0/_fScale));
//生成标注层
///////////////////////////////////////////////////////////////////
AcDbLayerTableRecord *pLayerTableRecord;
AcDbObjectId LayerTabRecordId;
AcDbLayerTable *pLayerTable;
AcDbObjectId ltypeObjId;
acdbHostApplicationServices()->workingDatabase()->getLayerTable(pLayerTable,AcDb::kForWrite);
if(pLayerTable->getAt("XBMarker",LayerTabRecordId) != Acad::eOk)
{
pLayerTableRecord=new AcDbLayerTableRecord;
pLayerTableRecord->setName("XBMarker" /*LayerName*/);
pLayerTable->add(LayerTabRecordId,pLayerTableRecord);
pLayerTableRecord->close();
}
pLayerTable->close();
}
void MarkPt(AcGePoint3d ptMark)
{
ads_point pt1,pt2;
double dAngle;
//是否为起点或终点
if(ptMark.distanceTo(ptStart)<0.01)
{
pt1[X] = ptStart.x;
pt1[Y] = ptStart.y;
pt2[X] = ptEnd.x;
pt2[Y] = ptEnd.y;
dAngle = ads_angle(pt1,pt2)+0.5*PI;
DrawBZ(ptMark,dAngle,m_dStartMile,0.0,LEFT);
return;
}
else if (ptMark.distanceTo(ptEnd)<0.01)
{
pt1[X] = ptStart.x;
pt1[Y] = ptStart.y;
pt2[X] = ptEnd.x;
pt2[Y] = ptEnd.y;
dAngle = ads_angle(pt1,pt2)+0.5*PI;
double dDist = ptStart.distanceTo(ptEnd);
double dMile = m_dStartMile + dDist/_fScale;
DrawBZ(ptMark,dAngle,dMile,0.0,LEFT);
return;
}
//计算垂足
AcGePoint3d ptChuiZu;
ChuizuToZx(ptChuiZu.x,ptChuiZu.y,ptMark.x,ptMark.y,ptStart.x,ptStart.y,ptEnd.x,ptEnd.y);
//标注点到起点的距离
double dDist=0.0;
dDist = ptChuiZu.distanceTo(ptStart);
double dCentrLineAngle=0.0;
pt1[X] = ptStart.x;
pt1[Y] = ptStart.y;
pt2[X] = ptEnd.x;
pt2[Y] = ptEnd.y;
dCentrLineAngle = ads_angle(pt1,pt2);
int nSide = CCWTest(ptStart,ptEnd,ptMark);
if (nSide == TURN_LEFT)
dAngle = dCentrLineAngle + 0.5*PI;
else
dAngle = dCentrLineAngle - 0.5*PI;
double dMile;
//检查标注的方向 是与指定方向相同 还是相反
double dDirection = (ptChuiZu.x - ptStart.x)*(ptEnd.x-ptStart.x) +(ptChuiZu.y - ptStart.y)*(ptEnd.y - ptStart.y);
if (dDirection>0)
dMile = m_dStartMile + dDist/_fScale;
else
dMile = m_dStartMile - dDist/_fScale;
double dDistMarkPtToLine = 0.0;
dDistMarkPtToLine = ptChuiZu.distanceTo(ptMark);
DrawBZ(ptMark,dAngle,dMile,dDistMarkPtToLine/_fScale,nSide);
}
//////////////////////////////////////////////////////////////////////////
//
// 该函数用来处理当一个里程上有两个标注点时的情况
// AcGePoint3d ptMark, 距离中线较远的标注点
// double dDist, 较远的距离值
// double dDist2 较近的距离值
//
//////////////////////////////////////////////////////////////////////////
void MarkPt(AcGePoint3d ptMark,double dDist,double dDist2)
{
ads_point pt1,pt2;
double dAngle;
//计算垂足
AcGePoint3d ptChuiZu;
ChuizuToZx(ptChuiZu.x,ptChuiZu.y,ptMark.x,ptMark.y,ptStart.x,ptStart.y,ptEnd.x,ptEnd.y);
double dCentrLineAngle=0.0;
pt1[X] = ptStart.x;
pt1[Y] = ptStart.y;
pt2[X] = ptEnd.x;
pt2[Y] = ptEnd.y;
dCentrLineAngle = ads_angle(pt1,pt2);
int nSide = CCWTest(ptStart,ptEnd,ptMark);
if (nSide == TURN_LEFT)
dAngle = dCentrLineAngle + 0.5*PI;
else
dAngle = dCentrLineAngle - 0.5*PI;
double dMile;
//检查标注的方向 是与指定方向相同 还是相反
double dDirection = (ptChuiZu.x - ptStart.x)*(ptEnd.x-ptStart.x) +(ptChuiZu.y - ptStart.y)*(ptEnd.y - ptStart.y);
double dDistToStartPt;
dDistToStartPt = ptChuiZu.distanceTo(ptStart);
if (dDirection>0)
dMile = m_dStartMile + dDistToStartPt/_fScale;
else
dMile = m_dStartMile - dDistToStartPt/_fScale;
DrawBZ(ptMark,dAngle,dMile,dDist/_fScale,dDist2/_fScale,nSide);
}
//一次性全部标注
void BZALL()
{
int rc;
ads_point pickPoint;
ads_name entityName;
AcDbObjectId entityId;
AcDbObject *pObj;
Acad::ErrorStatus estatus;
AcDbPolyline *pPolyLine = NULL;
AcDbLine *pLine = NULL;
while (rc = acedEntSel("\n请选择边界: ", entityName, pickPoint))
{
if (rc == RTCAN)
return;
if (rc == RTNORM)
{
acdbGetObjectId(entityId, entityName);
estatus = acdbOpenObject(pObj,entityId, AcDb::kForRead);
if (estatus != Acad::eOk )
{
return ;
}
if (pObj->isKindOf(AcDbPolyline::desc())) //修改直线
{
pPolyLine = AcDbPolyline::cast(pObj);
int nPts = pPolyLine->numVerts();
AcGePoint2d ptTemp,ptNext;
AcGePoint3d ptTemp3d,ptNext3d;
for (int k = 0; k< nPts; k++)
{
ads_point pt1,pt2;
double dAngle1,dAngle2;
double dDist1,dDist2;
AcGePoint3d ptChuiZu;
pPolyLine->getPointAt(k,ptTemp3d);
if (k+1<nPts)
{
//根据要求 需要检查该点的下一点是否与该点都在线路的法线方向上 是则只标注外侧点
pPolyLine->getPointAt(k+1,ptNext3d);
//计算下一点垂足
ChuizuToZx(ptChuiZu.x,ptChuiZu.y,ptNext3d.x,ptNext3d.y,ptStart.x,ptStart.y,ptEnd.x,ptEnd.y);
//计算
pt1[X] = ptNext3d.x;
pt1[Y] = ptNext3d.y;
pt1[Z] = 0.0;
pt2[X] = ptChuiZu.x;
pt2[Y] = ptChuiZu.y;
pt2[Z] = 0.0;
dDist2 = ads_distance(pt1,pt2);
if (dDist2 == 0)
MarkPt(ptNext3d);
//////////////////////////////////////////////////////////////////////////
//计算当前点垂足
ChuizuToZx(ptChuiZu.x,ptChuiZu.y,ptTemp3d.x,ptTemp3d.y,ptStart.x,ptStart.y,ptEnd.x,ptEnd.y);
//计算
pt1[X] = ptTemp3d.x;
pt1[Y] = ptTemp3d.y;
pt1[Z] = 0.0;
pt2[X] = ptChuiZu.x;
pt2[Y] = ptChuiZu.y;
pt2[Z] = 0.0;
dDist1 = ads_distance(pt1,pt2);
if (dDist1==0)
MarkPt(ptTemp3d);
//两点之间的方向 与 中线的法向是否是同向
pt1[X] = ptStart.x;
pt1[Y] = ptStart.y;
pt1[Z] = 0.0;
pt2[X] = ptEnd.x;
pt2[Y] = ptEnd.y;
pt2[Z] = 0.0;
dAngle1 = ads_angle(pt1,pt2)+0.5*PI;
pt1[X] = ptTemp3d.x;
pt1[Y] = ptTemp3d.y;
pt1[Z] = 0.0;
pt2[X] = ptNext3d.x;
pt2[Y] = ptNext3d.y;
pt2[Z] = 0.0;
dAngle2 = ads_angle(pt1,pt2);
//检查如果存在同一里程 两个边界点的情况则根据情况标注
if (fabs(sin(dAngle1 -dAngle2))<0.05)
{
//当前点距离中线近
if (dDist1 < dDist2)
MarkPt(ptNext3d,dDist2,dDist1);
else //当前点距离中线远
MarkPt(ptTemp3d,dDist1,dDist2);
k++;
continue;
}
}
MarkPt(ptTemp3d);
}
pObj->close();
return;
}
else if (pObj->isKindOf(AcDbLine::desc())) //修改直线
{
pLine = AcDbLine::cast(pObj);
AcGePoint3d ptTemp3d;
int nPts = pLine->getStartPoint(ptTemp3d);
MarkPt(ptTemp3d);
pLine->getEndPoint(ptTemp3d);
MarkPt(ptTemp3d);
pObj->close();
return;
}
else
{
ads_printf("选择的不是直线或多段线对象");
pObj->close();
continue;
}
}
}
}
void ConnectToExcel(CString strFileName)
{
//下面的很重要很重要
//********************************在使用组件时一定要初始化它*****************************
HRESULT hRes = CoInitialize(NULL);
AfxEnableControlContainer();
//3.创建Excel服务
if (!ExcelApp.CreateDispatch("Excel.Application",NULL))
{
AfxMessageBox("创建Excel服务失败!");
return ;
}
//4.利用模板文件建立新文档:
wbsMyBooks.AttachDispatch(ExcelApp.GetWorkbooks(),true);
//打开指定的Excel文件,得到当前Excel的工作薄
wbMyBook.AttachDispatch(wbsMyBooks.Add(_variant_t(strFileName)));
//5.得到Worksheets
wssMysheets.AttachDispatch(wbMyBook.GetWorksheets(),true);
//6.选定待保存数据的工作表
wsMysheet.AttachDispatch(wssMysheets.GetItem(_variant_t("sheet1")),true);
//得到全部Cells,此时,rgMyRge是cells的集合
rgMyRge.AttachDispatch(wsMysheet.GetCells(),true);
};
void DisconnectExcel()
{
//写Excel文件完成后必须按如下顺序卸载Excel服务,否则将会导致
wsMysheet.Activate();
ExcelApp.SetVisible(false);
ExcelApp.SetUserControl(false); //不调用excel表
//该语句必须在Excel 服务被卸载之前执行,否则其调用会无效,这将导致Excel实例在任务管理器中遗留
ExcelApp.Quit();
//卸载服务
rgMyRge.ReleaseDispatch();
wsMysheet.ReleaseDispatch();
wssMysheets.ReleaseDispatch();
wbMyBook.ReleaseDispatch();
wbsMyBooks.ReleaseDispatch();
ExcelApp.ReleaseDispatch();
};
// This is command 'BZ'
void BZ()
{
}
// This is command 'OPEN'
void XBopen()
{
//选择标注的地亩图文件
CFileDialog MyOpenDlg(TRUE);
CString strFileName="";
MyOpenDlg.m_ofn.lpstrTitle = "指定存储位置";
MyOpenDlg.m_ofn.lpstrDefExt = ".xls";
MyOpenDlg.DoModal();
strFileName = MyOpenDlg.GetPathName();
if (strFileName=="")
{
AfxMessageBox("无法打开指定文件");
return ;
}
else
{
ConnectToExcel(strFileName);
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -