www.pudn.com > CADtool.rar > PS_jbz.lsp, change:2009-04-04,size:15125b


;;;------------------------------------------------------------- 
;;; 读取井布置数据文件,成功则返回数据表,否则返回nil 
;;;数据文件每行格式:里程   左右侧   井中心与中线距离 
(defun GetJBZDateFromFile (/ FileName File1 str jbzList ZhuoYou LiCheng JuLi ch) 
 (setq jbzList nil) 
 (if (setq FileName (getfiled "选择检查井布置文件" "" "jbz" 4)) 
  (progn 
   ;;读模式打开检查井布置文件 
   (setq File1 (open FileName "r")) 
 
   ;;逐行读入 
   (while (setq str (read-line File1)) 
      (setq LiCheng (read str)) 
      ;;取得井里程 
      (if (numberp LiCheng) 
       (progn 
        (while (/= (setq ch (substr str 1 1)) " ") 
          (setq str (substr str 2)) 
         ) 
        (while (= (setq ch (substr str 1 1)) " ") 
          (setq str (substr str 2)) 
         )        
        
        (setq ZhuoYou "") 
        (while (/= (setq ch (substr str 1 1)) " ") 
         (setq ZhuoYou (strcat ZhuoYou ch)) 
 
         (setq str (substr str 2)) 
        ) 
        (cond 
         ( (or (= ZhuoYou "z") (= ZhuoYou "Z")) 
            (setq  ZhuoYou "左侧") ) 
         ( (or (= ZhuoYou "y") (= ZhuoYou "Y")) 
            (setq  ZhuoYou "右侧") ) 
         ( (or (= ZhuoYou "s") (= ZhuoYou "S")) 
            (setq  ZhuoYou "双侧") ) 
         (T (setq ZhuoYou "错误格式")) 
        )  
         
        ;;取得左右侧 
        (if (or (= ZhuoYou "左侧") 
                (= ZhuoYou "右侧") 
                (= ZhuoYou "双侧") 
             )  
         (progn 
          (while (= (setq ch (substr str 1 1)) " ") 
           (setq str (substr str 2)) 
          ) 
          (setq JuLi (read str)) 
          ;;取得井与路中线距离 
 
          (if (numberp JuLi) 
           (setq jbzList (append jbzList (list (list LiCheng ZhuoYou JuLi)))) 
          ) 
         ) 
        ) 
       ) 
      ) 
   ) 
   (close File1)    ;关闭文件 
  ) 
 ) 
 jbzList 
) 
;;;------------------------------------------------------------- 
;;;按三种方式进行布井 
;;;1.从数据文件读入数据、绘制 
;;;2.按指定区间布置 
;;;3.手选坐标逐个布置 
(defun C:PS_jbz (/           jbzList     jbzListN    k 
                  ;;按井布置数据文件布井的参数 
                  kA          kB          kTmp        kDist       n 
                  ;;区间布置模式的开始里程、终点最大里程、里程增量、井设置次数 
                  jpPt1       LjpPt1 
                  ;;当前坐标与中线的垂足、垂足到曲线起点的距离 
                  kw ;控制布井循环变量 
                  ListTemp    StrTmp      xiaoshuTmp  ptTmp       OM          tmp 
                  ;;临时变量 
                  nob         obc         obl         oblname     QiDianLiCheng           LiChengFangXiang 
                  ZhongDianLiCheng        LZhongXiang  strLiChengQianZhui 
                  ;;( 中线  中线起点里程  里程增加与曲线正向的关系  终点里程  中线长  里程前缀 ) 等相关变量 
                  floatMinLiCheng floatMaxLiCheng  
                  LiCheng     PtoZDist 
                  ;;点里程,点与中线的距离 
                  ZhuoYou ;点在道路左侧还是右侧                   
                  HintText    HintTextEName ;用作动态提示时的文本 
                  JinEName    JinEData    PtJin ;井相关 
                 ) 
;;;------------------------------------------------------------- 
;;;绘单个井 
 (defun drawSingleJin () 
  (setq PtJin (car (getPointByLiChengZhuoYouJuLi 
               oblname LZhongXiang QiDianLiCheng LiChengFangXiang ZhongDianLiCheng LiCheng ZhuoYou PtoZDist) ) 
  ) 
  (if PtJin 
   (if (not HintText) 
    (progn 
     (AddCircle PtJin #RJin#) 
     ;;若未设置动态提示文本,且井中心坐标计算成功,画圆 
     (SetXdata (entlast) 
            (list "PS_Jin" 
                  (cons 1000 "检查井") 
            ) 
      ) ;添加井类型标记的扩展数据 
     ) 
 
    (progn 
     (entmod (subst (cons 10 PtJin) (assoc 10 JinEData) JinEData)) 
     (entupd JinEName) 
 
     (entdel HintTextEName) 
     (setq HintText nil) 
    )               ;若已设置动态提示文本,更新圆、提示文本 
   )                ;井坐标计算成功时绘井   
  ) 
 ) 
;;;------------------------------------------------------------- 
;;;若已设置动态提示文本,删除圆、提示文本 
(defun clearHint() 
  (if HintText 
      (progn 
       (entdel JinEName) 
       (entdel HintTextEName) 
       (setq HintText nil) 
       ) 
      ) 
) 
;;;------------------------------------------------------------- 
;;;出错时清除提示 
(defun *error* (msg) 
 (clearHint) 
 (princ) 
)  
;;;------------------------------------------------------------- 
 (if (setq ListTemp (GetZhongXiang "否")) ;如果成功设置中线 
  (progn 
   (setq HintText nil 
         Jin nil          
   )                ;变量初始化 
   (setq oblname            (nth 0 ListTemp) 
         QiDianLiCheng      (nth 1 ListTemp) 
         LiChengFangXiang   (nth 2 ListTemp) 
         ZhongDianLiCheng   (nth 3 ListTemp) 
         LZhongXiang        (nth 4 ListTemp) 
         strLiChengQianZhui (nth 5 ListTemp) 
   )                ;确定:中线  中线起点里程  里程增加与曲线正向的关系  终点里程  中线长 里程前缀 
   
   (if (= LiChengFangXiang "同向") 
    (progn 
       (setq floatMinLiCheng QiDianLiCheng) 
       (setq floatMaxLiCheng (+ QiDianLiCheng LZhongXiang)) 
       ) 
     (progn 
       (setq floatMaxLiCheng QiDianLiCheng) 
       (setq floatMinLiCheng (- QiDianLiCheng LZhongXiang)) 
       ) 
      )  
 
    
   (command "-layer" "m" "检查井" "") ;建立名称为"检查井"的图层,用于程序画检查井 
;;;------------------------------------------------------------- 
;;;以下按三种方式进行布井 
;;;1.从数据文件读入数据、绘制 
;;;2.按指定区间布置 
;;;3.手选坐标逐个布置 
   (princ 
    "\n点取需要布井的位置[按数据文件布井(F)/按区间布井(L)/参数设置(S)/退出(X)]:" 
   ) 
   (setq kw t) 
   (while kw 
    ;;动态布井等 
    ;;(initget 4 "F L S X") 
    (setq tmp (grread t 4 1)) 
 
    (cond 
     ((= (car tmp) 2) ;如果用户输入字符 
      (cond         ;二次分支 
       ;;二次分支一:从数据文件读入数据、绘制 
       ((or (= (cadr tmp) (ascii "f")) 
            (= (cadr tmp) (ascii "F")) 
        ) 
        (clearHint) 
        (setq jbzList (GetJBZDateFromFile)) 
        (if jbzList 
         (progn 
          (setq OM (getvar "osmode")) 
          (setvar "osmode" 0) 
 
          (setq k 0) 
          (repeat (length jbzList) 
           (setq jbzListN (nth k jbzList)) 
           (setq LiCheng  (nth 0 jbzListN ) 
                 ZhuoYou  (nth 1 jbzListN ) 
                 PtoZDist (nth 2 jbzListN ) 
           ) 
 
           (if (= ZhuoYou "双侧") 
            (progn 
             (setq ZhuoYou "左侧") 
             (drawSingleJin) 
             (setq ZhuoYou "右侧") 
             (drawSingleJin) 
            )       ;双侧布井时,先布左侧井,后布右侧井 
 
            (drawSingleJin) ;单侧布井是,直接布置 
           ) 
 
           (setq k (1+ k)) 
          )         ;根据数据表,逐行绘井 
 
          (setvar "osmode" OM) 
         ) 
        ) 
 
        (princ 
         "\n点取需要布井的位置[按数据文件布井(F)/按区间布井(L)/参数设置(S)/退出(X)]:" 
        ) 
       ) 
       ;;二次分支二:按指定区间布置 
       ((or (= (cadr tmp) (ascii "l")) 
            (= (cadr tmp) (ascii "L")) 
        ) 
        (clearHint) 
         
        (initget 4) 
        (setq kA (if (setq xiaoshuTmp (getreal (strcat "\n输入布井区间的里程起点<" 
                                                       (rtos floatMinLiCheng 2 3) 
                                                       ">:" 
                                               ) 
                                       ) 
                      )                  
                  xiaoshuTmp 
                  floatMinLiCheng 
                 ) 
        ) 
 
        (initget 4) 
        (setq kB (if (setq xiaoshuTmp (getreal (strcat "\n输入布井区间的里程终点<" 
                                                       (rtos floatMaxLiCheng 2 3) 
                                                       ">:" 
                                               ) 
                                      ) 
                     ) 
                  xiaoshuTmp 
                  floatMaxLiCheng 
                 ) 
        ) 
 
        (initget 6) 
        (setq kDist (if (setq xiaoshuTmp (getreal "\n输入布井的井间距<30>:")) 
                     xiaoshuTmp 
                     30 
                    ) 
        ) 
 
        (initget "Z Y B") 
        (setq ZhuoYou (getkword "\n井布置在道路[左侧(Z)/右侧(Y)/双侧(B)]<Z>:")) 
        (cond 
         ((= ZhuoYou "B") (setq ZhuoYou "双侧")) 
         ((= ZhuoYou "Y") (setq ZhuoYou "右侧")) 
         (T (setq ZhuoYou "左侧")) 
        ) 
 
        (initget 5) 
        (setq PtoZDist (getreal "\n输入井中心(圆心)与路中线的距离:")) 
        (setq PtoZDist (fixReal PtoZDist #ZhuLiXiaoShu#)) 
 
 
        (if (> kA kB) 
         (progn 
          (setq kTmp kA) 
          (setq kA kB) 
          (setq kB kTmp) 
         ) 
        ) 
        ;;如果区间的开始里程比终点里程小,则将里程互换 
        ;;以上初始化 
 
        (setq OM (getvar "osmode")) 
        (setvar "osmode" 0) 
 
        (setq LiCheng kA 
              n 1 
        ) 
        (setq LiCheng (fixReal LiCheng #LiChengXiaoShu#)) 
        (while (<= LiCheng kB) 
         (if (= ZhuoYou "双侧") 
          (progn 
           (setq ZhuoYou "左侧") 
           (drawSingleJin) 
           (setq ZhuoYou "右侧") 
           (drawSingleJin) 
           (setq ZhuoYou "双侧") 
          )         ;双侧布井时,先布左侧井,后布右侧井,再把“左右侧”参数还原 
 
          (drawSingleJin) ;单侧布井是,直接布置 
         ) 
 
         (setq LiCheng (+ KA (* n kDist))) 
         (setq n (1+ n)) 
        ) 
 
        (setvar "osmode" OM) 
        (princ 
         "\n点取需要布井的位置[按数据文件布井(F)/按区间布井(L)/参数设置(S)/退出(X)]:" 
        ) 
       ) 
 
       ;;二次分支三:设置布井的有关参数 
       ((or (= (cadr tmp) (ascii "s")) 
            (= (cadr tmp) (ascii "S")) 
        ) 
        (clearHint) 
         
        (initget 4) 
        (setq StrTmp (strcat "\n输入布井时里程需要保留的小数位数[0/1/2]<当前为" 
                             (rtos #LiChengXiaoShu# 2 0) 
                             "位>:" 
                     ) 
        ) 
        (setq #LiChengXiaoShu# 
              (fix (if (setq xiaoshuTmp (getint StrTmp)) 
                    xiaoshuTmp 
                    #LiChengXiaoShu# 
                   ) 
              ) 
        ) 
        (if (> #LiChengXiaoShu# 2) 
         (setq #LiChengXiaoShu# 1) 
        ) 
 
        (initget 4) 
        (setq StrTmp (strcat "\n输入布井时井与路中线距离需要保留的小数位数[0/1/2]<当前为" 
                             (rtos #ZhuLiXiaoShu# 2 0) 
                             "位>:" 
                     ) 
        ) 
        (setq #ZhuLiXiaoShu# 
              (fix (if (setq xiaoshuTmp (getint StrTmp)) 
                    xiaoshuTmp 
                    #ZhuLiXiaoShu# 
                   ) 
              ) 
        ) 
        (if (> #ZhuLiXiaoShu# 2) 
         (setq #ZhuLiXiaoShu# 1) 
        ) 
 
        (initget 6) 
        (setq StrTmp (strcat "\n输入井(圆)半径<当前为" (rtos #RJin# 2 2) ">:")) 
        (setq xiaoshuTmp (getreal StrTmp)) 
        (if (numberp xiaoshuTmp ) 
         (setq #RJin# xiaoshuTmp) 
        ) 
 
        (princ 
         "\n点取需要布井的位置[按数据文件布井(F)/按区间布井(L)/参数设置(S)/退出(X)]:" 
        ) 
       ) 
 
       ;;二次分支四:退出程序 
       ((or (= (cadr tmp) (ascii "x")) 
            (= (cadr tmp) (ascii "X")) 
        ) 
        (setq kw nil) 
       ) 
 
       ;;二次分支默认:什么都不做 
       (T nil) 
      ) 
     ) 
 
     ((= (car tmp) 3) 
                    ;按下了鼠标左键, 绘井时,根据要求的里程、点到路线距离的小数位数重新计算井中心坐标,布井 
      (setq OM (getvar "osmode")) 
      (setvar "osmode" 0) 
 
      (setq ptTmp (cadr tmp)) 
 
      (setq jpPt1 (vlax-curve-getClosestPointTo oblname ptTmp T)) 
                    ; 取得给定点与中线的垂足坐标 
      (setq LjpPt1 (vlax-curve-getDistAtPoint oblname jpPt1)) 
 
      (setq PtoZDist (fixReal (distance jpPt1 ptTmp) #ZhuLiXiaoShu#)) 
 
      (if (= LiChengFangXiang "同向") 
       (setq LiCheng (+ QiDianLiCheng LjpPt1)) 
       (setq LiCheng (- QiDianLiCheng LjpPt1)) 
      )             ; 计算坐标点的里程数值 
      (setq LiCheng (fixReal LiCheng #LiChengXiaoShu#)) 
 
      (setq ZhuoYou (strZhuoYou oblname ptTmp jpPt1 LjpPt1 LiChengFangXiang)) 
                    ;确定坐标在道路中线的左或右侧 
 
      (drawSingleJin) ;绘单个井 
 
      (setvar "osmode" OM) 
      (princ 
       "\n点取需要布井的位置[按数据文件布井(F)/按区间布井(L)/参数设置(S)/退出(X)]:" 
      ) 
     ) 
 
     ((= (car tmp) 5) ;移动了光标,动态提示当前坐标的里程、左右侧、与路线距离 
      (setq OM (getvar "osmode")) 
      (setvar "osmode" 0) 
 
      (setq ptTmp (cadr tmp)) 
 
      (setq jpPt1 (vlax-curve-getClosestPointTo oblname ptTmp T)) 
                    ; 取得给定点与中线的垂足坐标 
      (setq LjpPt1 (vlax-curve-getDistAtPoint oblname jpPt1)) 
                    ;点与起点之间的曲线段长 
      (if (and (<= 0.001 LjpPt1) (< LjpPt1 LZhongXiang)) 
                    ;判断点里程是否为有效里程时,并进行相应操作 
                    ;0.001为用于判断点在道路左右侧时需要的长度,需要调整时查看strZhuoYou函数 
       (progn 
        (setq PtoZDist (distance jpPt1 ptTmp)) ;点到路中线距离 
 
        (if (= LiChengFangXiang "同向") 
         (setq LiCheng (+ QiDianLiCheng LjpPt1)) 
         (setq LiCheng (- QiDianLiCheng LjpPt1)) 
        )           ; 计算坐标点的里程数值 
 
        (setq ZhuoYou (strZhuoYou oblname ptTmp jpPt1 LjpPt1 LiChengFangXiang)) 
        (setq StrTmp (rtoZhuanHao LiCheng strLiChengQianZhui)) 
        (setq StrTmp (strcat StrTmp "," ZhuoYou (rtos PtoZDist 2 2))) 
       ) 
 
       (setq StrTmp "当前点不在中线所确定的里程范围内!") 
      )             ;计算提示文本内容       
 
      (if (not HintText) 
       (progn 
        (AddCircle ptTmp #RJin#) 
        (setq JinEName ( entlast)) 
        (setq JinEData (entget JinEName )) 
         
        (SetXdata JinEName (list "PS_Jin" (cons 1000 "检查井") ) ) ;添加井类型标记的扩展数据 
         
        (vl-cmdf "text" 
                 (polar ptTmp (/ pi -2) (* 5 #RJin#)) 
                 (* 3 #RJin#) 
                 0 
                 StrTmp 
        ) 
        (setq HintTextEName (entlast)) 
        (setq HintText (entget HintTextEName)) 
       )            ;若未设置动态提示文本,画圆,写提示 
 
       (progn 
        (entmod (subst (cons 10 ptTmp) (assoc 10 JinEData) JinEData) 
        ) 
        (entupd JinEName) 
 
        (setq HintText (subst (cons 1 StrTmp) (assoc 1 HintText) HintText)) 
        (entmod (subst (cons 10 (polar ptTmp (/ pi -2) (* 5 #RJin#))) 
                       (assoc 10 HintText) 
                       HintText 
                ) 
        ) 
        (entupd HintTextEName) 
       )            ;若已设置动态提示文本,更新圆、提示文本 
      ) 
 
      (setvar "osmode" OM) 
     ) 
 
     (T             ;其它情况,退出程序 
      (setq kw nil) 
     ) 
    ) 
   ) 
    
  (clearHint) 
  ) 
 ) 
 (setvar "osmode" 16383) 
 (princ) 
) 
;;;-------------------------------------------------------------