📄 annolink.mc
字号:
/*================================================================================
Step by step 之 MDL 快速入门实例十四
================================================================================*/
#include <mselems.h>
#include <dbdefs.h>
#include <dberrs.h>
#include <string.h>
#include <mdl.h>
#include <scanner.h>
#include <basetype.h>
#include <rdbmslib.fdf>
#include <mslinkge.fdf>
#include <mslstyle.h>
#include <dlogitem.h>
#include <cexpr.h>
#include <userfnc.h>
#include <cmdlist.h>
#include <colrname.h>
#include <stdarg.h>
#include <dlogids.h>
#include <dlogitem.h>
#include <stdlib.h>
#include <stdio.h>
#include <tcb.h>
#include <dlogman.fdf>
#include <mselemen.fdf>
int COLOR_HEIGHTPOINT=6;
int LEVEL_HEIGHTPOINT=8;
int COLOR_HEIGHTTEXT=2;
int LEVEL_HEIGHTTEXT=14;
typedef struct tagAnnotationLinkage{
ULong fpos1, fpos2;
}AnnotationLink;
AnnotationLink annolink[2000];
void GetFirstPoint(MSElementDescr *emd, Dpoint3d *dp);
int annocount=0;
double TOLERANCE=0.2;
double SCALE=500;
int annoLink_save(ULong fp1, ULong fp2)
{
if (annocount>=2000-1)
{
mdlDialog_openInfoBox("图中关联注记太多,超出程序处理能力!");
return FALSE;
}
annolink[annocount].fpos1=fp1;
annolink[annocount++].fpos2=fp2; //记数用annocount
return TRUE;
}
int annoLink_findFirst(ULong fp)
{
int i;
for (i=0; i<annocount; i++)
if (annolink[i].fpos1==fp || annolink[i].fpos2==fp) return i+1; //id号从1开始,是人为地添加的,保存高程点及文本注记在数组annolink[2000]中以0开始
return -1;
}
int annoLink_findNext(ULong fp, int cur) //一个文本值关联二个高程点的情况 文本值的位置fp是一样的,而高程点的位置不一样,所以要用"||"
{
int i;
for (i=cur+1; i<annocount; i++)
if (annolink[i].fpos1==fp || annolink[i].fpos2==fp) return i+1;
return -1;
}
//添加注记关联linkage
void sdElmdscr_saveID(MSElementDescr *elmDP, ULong id)
{
ULong data[2];
data[0]=0x00991003;
data[1]=id;
mdlElement_appendAttributes(&elmDP->el, 4, (short *)data);
}
// 写日志文件
void Create_log_File(FILE *fpCoord, double Height_Pointx, double Height_Pointy, int errtype)
{
fprintf(fpCoord,"%5d %19.6lf %19.6lf\n",errtype,Height_Pointx,Height_Pointy);
}
// 在指定坐标周围寻找文本注记
// 返回找到的数量和第一个的位置
int FindElement(double Height_Pointx, double Height_Pointy, ULong *pos)
{
int i,number,mScanWords,mStatus,mElmNum;
Scanlist mScanList;
ULong mNextFilePos,mRetPos[100],mActualPos;
MSElementDescr *elmDP;
Dpoint3d dpoint;
int color,level,type;
double range;
// Scan all text elements in range
mdlScan_initScanlist(&mScanList);
mScanList.scantype = ELEMTYPE|NESTCELL;
mScanList.extendedType=FILEPOS;
mdlScan_noRangeCheck(&mScanList);
range=TOLERANCE*SCALE; // 搜索矩形半宽
mdlCnv_masterToUOR(&(range), range, MASTERFILE);
dpoint.x=Height_Pointx-range; dpoint.y=Height_Pointy-range; dpoint.z=0;
mScanList.xlowlim=mdlCnv_toScanFormat(dpoint.x); // scan range
mScanList.ylowlim=mdlCnv_toScanFormat(dpoint.y);
dpoint.x=Height_Pointx+range; dpoint.y=Height_Pointy+range; dpoint.z=0;
mScanList.xhighlim=mdlCnv_toScanFormat(dpoint.x);
mScanList.yhighlim=mdlCnv_toScanFormat(dpoint.y);
mdlScan_setDrawnElements(&mScanList);
mdlScan_initialize(0, &mScanList);
number=0;
do{
mScanWords=sizeof(mRetPos)/sizeof(UShort);
mStatus=mdlScan_file(mRetPos, &mScanWords, sizeof(mRetPos), &mNextFilePos);
mElmNum=mScanWords/sizeof(UShort);
for(i=0;i<mElmNum;i++) /* The circulation manipulate all points that accord with condition */
{
mdlElmdscr_read(&elmDP,mRetPos[i],0,0,&mActualPos);
type=elmDP->el.hdr.ehdr.type;
if (type!=8 && type!=9 && type!=10 && type!=66 && type!=5)
{
if (elmDP->h.firstElem!=NULL)
{
level=elmDP->h.firstElem->el.ehdr.level;
mdlElement_getSymbology(&color,NULL,NULL,&elmDP->h.firstElem->el);
}
else
{
mdlElement_getProperties(&level,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&elmDP->el);
mdlElement_getSymbology(&color,NULL,NULL,&elmDP->el);
}
}
if(color==COLOR_HEIGHTTEXT && level==LEVEL_HEIGHTTEXT)
{
number=number+1;
if(number==1) *pos=mRetPos[i];
}
mdlElmdscr_freeAll(&elmDP);
}
}while(mStatus==BUFF_FULL);
return number;
}
int process(char *fntag, char *fnlog)
{
FILE *ftag, *flog;
ULong filepos, nextpos, topos;
MSElementDescr *emd;
int color, level, type, count;
double Height_Pointx, Height_Pointy;
int id;
char fname[256], *tmp, str[256];
char path[256],newpath[256];
char *pname,*newpname;
char Text_string[100];
Dpoint3d dp;
int i,mScanWords,mStatus,mElmNum;
Scanlist mScanList;
ULong mNextFilePos,mRetPos[100],mActualPos,pos1;
MSElementDescr *elmDP;
double text_Pointx,text_Pointy;
flog=fopen(fnlog,"w+"); // 创建日志文件
if (!flog) return FALSE;
// search for possible annotation links
annocount=0;
filepos=0;
while(nextpos=mdlElmdscr_read(&emd,filepos,0,0,&filepos))
{
type=emd->el.hdr.ehdr.type;
if (type!=8 && type!=9 && type!=10 && type!=66 && type!=5)
{
if (emd->h.firstElem!=NULL)
{
level=emd->h.firstElem->el.ehdr.level;
mdlElement_getSymbology(&color,NULL,NULL,&emd->h.firstElem->el);
}
else
{
mdlElement_getProperties(&level,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&emd->el);
mdlElement_getSymbology(&color,NULL,NULL,&emd->el);
}
if(color==COLOR_HEIGHTPOINT && level==LEVEL_HEIGHTPOINT) // 是高程点
{
GetFirstPoint(emd, &dp);
Height_Pointx=dp.x;
Height_Pointy=dp.y;
count=FindElement(Height_Pointx, Height_Pointy, &topos); //参数同时变化!!!!!!
if(count==1) // 正好一一对应,匹配成功
{
if (annoLink_save(filepos, topos)==FALSE) break; // 缓冲区已满,不必再找。 分别是高程点,高程文本之文件位置
}
else // 否则记入日志文件
{
mdlCnv_UORToMaster(&(Height_Pointx), Height_Pointx, MASTERFILE);
mdlCnv_UORToMaster(&(Height_Pointy), Height_Pointy, MASTERFILE);
Create_log_File(flog, Height_Pointx, Height_Pointy, count);
}
}
}
filepos=nextpos;
mdlElmdscr_freeAll(&emd);
}
fclose(flog);
ftag=fopen(fntag, "wb+");
if (!ftag) return FALSE;
// create new design with annotation linkage
filepos=0;
while(nextpos=mdlElmdscr_read(&emd,filepos,0,0,&filepos))
{
/*+++++++++++++++++++++++++++++++++++++++++++++++
这里也有错误:
1.找的时候是把高程点的filepos存成fpos1,注记文本的filepos为fpos2,
所以找的时候不能混用;
2.添加linkage时对高程点和高程注记是不同的linkage来添加;
3.上面的存储方式不可能出现一个高程点对应几个高程信息的情况,所以
在查找的时候只要遍历存下的高程点的filepos就行了
------------------------------------------------*/
id=annoLink_findFirst(filepos);
while (id>0)
{
sdElmdscr_saveID(emd,id);
id=annoLink_findNext(filepos,id);
}
mdlWorkDgn_write(emd,-1,ftag,0,0);
filepos=nextpos;
mdlElmdscr_freeAll(&emd);
}
fclose(ftag);
return TRUE;
}
void main (int argc,char *argv[])
{
char filename[256],filename1[256];
char fname[256], *tmp, str[256];
char path[256],newpath[256];
char *pname,*newpname;
FindFileInfo *fileInfoP;
int fileCount;
if (argc>2) sscanf(argv[2], "%d", &LEVEL_HEIGHTPOINT);
if (argc>3) sscanf(argv[3], "%d", &COLOR_HEIGHTPOINT);
if (argc>4) sscanf(argv[4], "%d", &LEVEL_HEIGHTTEXT);
if (argc>5) sscanf(argv[5], "%d", &COLOR_HEIGHTTEXT);
if (argc>6) sscanf(argv[6], "%lf", &TOLERANCE);
if(mdlDialog_fileOpen(path, NULL, NULL, NULL, NULL, tcb->dgnfilenm, "请指定要处理的任一文件,同目录下所有文件都将处理")==TRUE)
{
strcpy(str,"你取消了这次操作");
mdlOutput_prompt(str);
goto end;
}
//选定要处理的文件
strcpy(newpath, path);
newpname=strrchr(newpath, '\\');
strcpy(newpname,"\\new\\");
newpname=strrchr(newpath, '\\')+1;
//确定定目标文件目录
pname=strrchr(path, '\\')+1;
strcpy(pname, "*.*");
mdlFile_findFiles (&fileInfoP, &fileCount, path, FF_NORMAL);
while (fileCount)
{
fileCount--;
strcpy(pname, fileInfoP[fileCount].name); //源文件名
strcpy(newpname, fileInfoP[fileCount].name); //目标文件名
strcpy(fname, newpath);
tmp=strrchr(fname,'.');
strcpy(tmp, ".log"); //日志文件名
mdlSystem_newDesignFile(path);
process(newpath, fname);
}
free (fileInfoP);
mdlOutput_status("大功告成啦!");
end: mdlSystem_unloadMdlProgram("annolink");
}
void GetFirstPoint(MSElementDescr *emd, Dpoint3d *dp)
{
switch (emd->el.ehdr.type)
{
case 2:
mdlCell_extract(dp, NULL, NULL, NULL, NULL, &emd->el);
break;
case 17:
mdlText_extract(NULL, dp, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &emd->el);
break;
default:
if (mdlElmdscr_extractEndPoints(dp, NULL, NULL, NULL, emd, 0)!=SUCCESS)
{
dp->x=0, dp->y=0, dp->z=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -