⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ydtcommands.cpp

📁 用于既有线纵坡拟合的工具,可以准确的通过最小二乘法拟合出具有最小抬落道量的坡度线
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	//指定前点,后点
	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 + -