Re: Объём земляных работ

Добрый день. Хочется вот чего: Есть пример (DWG). Для вычисления разницы отметок использую этот LISP

(defun c:raz2 (/ ss el spmr delta att seqend a_name new_value att0 att)
          ;| 
вычисляет разницу между проектными и существующими отметками
и вставляет её в блок otm01
    
|;
;;;  ===========; считывание  атрибутов в список ss  ======================
  (setq ss nil)
  (while (null ss)
    (setq ss (ssget '((0 . "INSERT") (2 . "OTM01"))
         ) ;_ конец ssget
    ) ;_ setq
  ) ;_ while
;;;  (setq el (car (entsel "\nУкажите блок: ")))
;;;      Цикл чтение АТРИБУТОВ
  (setq i 0)
  (if ss
    (progn
      (while (setq el (ssname ss i)) ; el -   примитив

    (setq att (entnext el))
    (setq seqend (cdr (assoc 0 (entget att))))
;;;                    ; пока есть атрибуты в блоке
    (while (not (eq seqend "SEQEND"))
;;;                    ; имя атрибута
      (setq    att_name  (cdr (assoc 2 (entget att)))
        att_value (cdr (assoc 1 (entget att))) ; значение
        att_value (if (= att_value "")
                "0"
                att_value
              ) ;_ if
      ) ;_ setq
      (cond
        ((= att_name "DELTA") (setq mar (list "DELTA" att_value)))
        ((= att_name "RED") (setq mar (list "RED" att_value)))
        ((= att_name "BLACK") (setq mar (list "BLACK" att_value)))
      ) ;_ cond

      (setq    spmr (cons mar spmr)
      ) ;_ конец setq
      (setq    att (entnext att)
        att_value nil
      ) ;_ setq
      (setq seqend (cdr (assoc 0 (entget att))))
    ) ;_ конец while


    (setq delta (- (atof (car (cdr (assoc "RED" spmr))))
               (atof (car (cdr (assoc "BLACK" spmr))))
            ) ;_ конец -
          delta
;;;     (vl-string-subst
;;;        ","
;;;        "."
            (strcat (if    (> delta 0)
                  "+"
                  ""
                ) ;_ конец if
                (rtos delta 2 2)
            ) ;_ конец strcat
;;;          ) ;_ конец vl-string-subst
    ) ;_ конец setq
    (nz_att_ch10 el (list (list "DELTA" delta)))
        (setq     i       (1+ i))

      ) ;_ конец while
    ) ;_ конец progn
    (prompt
      "\n Блоков маркировки отметок земли - не найдено"
    ) ;_ конец prompt
  ) ;_ конец if
  (princ)
) ;_ конец defun

                          
;;; ===================      ЗАМЕНА ЗНАЧЕНИЙ АТРИБУТОВ ========================================
(defun nz_att_ch10
       (el_sp sp_atr / att seqend a_name new_value att0 att)
;;;    el_sp - элемент списка
;;;     new_value - новое значение
  (setq att (entnext el_sp))
  (setq seqend (cdr (assoc 0 (entget att))))
  (while (not (eq seqend "SEQEND"))
                  ; пока есть атрибуты в блоке
    (setq a_name (cdr (assoc 2 (entget att)))) ; находим  атрибут

;;; начинаем проверять по списку для изменений: есть - меняем
    (setq new_value (car (cdr (assoc a_name sp_atr))))

    (if    new_value
      (setq att0 (subst    (cons 1 new_value)
            (assoc 1 (entget att))
            (entget att)
         ) ;_ конец subst
      ) ;_ конец setq
    ) ;_ конец if
    (entmod att0)
    (entupd att)
    (setq att (entnext att))
    (setq seqend (cdr (assoc 0 (entget att))))
  ) ;_ конец while
) ;_ конец defun 

Затем требуется вычислить объём фигуры (насыпь/выемка).
Хотелось бы использовать ЭТОТ LISP (или другой)

(DEFUN c:ob  (/ I NABOR NN PLO SUMA TEXT OLD_DIM) 
;| 
вычисляет объем срезки\насыпи по разнице отметок и площаде фигуры 
|; 
  (setq OLD_DIM (getvar "dimzin")) 
  (IF 
    (AND 
      (SETQ nabor (SSGET '((0 . "*text") (1 . "(*)") (62 . 5)))) 
      (SETQ plo (ENTSEL "\nУчасток: ")) 
      (SETQ plo (CAR plo)) 
      (SETQ plo (VLA-GET-AREA (VLAX-ENAME->VLA-OBJECT plo))) 
      ) 
     (PROGN 
       (SETQ nn     (SSLENGTH nabor) 
        i     -1 
        suma 0.0) 
       (REPEAT nn 
    (SETQ suma 
      (+ 
        suma 
        (ATOF 
          (VL-STRING-TRIM 
            "()" 
            (CDR 
         (ASSOC 
           1 
           (ENTGET (SSNAME nabor (SETQ i (1+ i)))))))))) 
    ) 
       (SETQ suma (* (/ suma nn) plo)) 
       (VL-CMDF   "_.copy" 
      (SSNAME nabor 0) 
      "" 
      "_none" 
      '(0 0 0) 
      "_none" 
      '(0 0 0)) 
       (SETQ text (ENTGET (ENTLAST))) 
       (setvar "dimzin" 4) 
       (ENTMOD 
    (SUBST   (CONS 1 (RTOS suma 2 2)) 
      (ASSOC 1 text) 
      text)) 
       (setvar "dimzin" OLD_DIM) 
       (VL-CMDF "_.change" "_l" "" "_p" "_co" 1 "") 
       (VL-CMDF   "_.move" 
      "_l" 
      "" 
      "_none" 
      (CDR (ASSOC 10 (ENTGET (ENTLAST)))) 
      ) 
       ) 
     ) 
  )

чтоб значения брались из блока otm01 из атрибута DELTA путем выбора блоков, и выбора фигуры получался объём.
Т.е. вводишь команду -> выбираешь блоки (программа считывает значения из атрибута DELTA и вычисляет среднее) ->Enter -> выбираешь полилинию и получаешь объём насыпи или выемки в виде текста, который можно вставить.
Посмотрите, пожалуйста, можно ли такое реализовать?

Post's attachments

пример_otm01.dwg 639.71 Кб, 6 скачиваний с 2019-08-06 

You don't have the permssions to download the attachments of this post.

(изменено: Alan, 8 августа 2019г. 16:34:16)

Re: Объём земляных работ

Erema_Misha пишет:

чтоб значения брались из блока otm01 из атрибута DELTA путем выбора блоков, и выбора фигуры получался объём.

Выбрать 4 значения DELTA из 4-х блоков, проблем нет.
Примерный алгоритм запроса:
Выберите номер участка ---> (это текст в центре квадрата?)
Выберите четыре угла участка ---> это 4 блока по углам,

и вычисляет среднее) ->Enter -> выбираешь полилинию и получаешь объём насыпи или выемки

На что умножать среднее значение чтобы получить объём, на площадь полилинии?
Не геодезист я...

(изменено: Erema_Misha, 9 августа 2019г. 15:12:56)

Re: Объём земляных работ

Алгоритм такой:
вводишь команду -> предлагается выбрать блоки (их может быть от любое количество, не обязательно 4, т.к. фигуры могут быть разные) -> выбираешь блоки (программа считывает значения из атрибута DELTA и вычисляет среднее) ->Enter -> предлагает выбрать полилинию->выбираешь полилинию Enter ->
спрашивает куда вставить текст (мультитекст) с отображением знаков +или- .
-------------------
Да. на площадь полилинии.

(изменено: Alan, 12 августа 2019г. 11:55:55)

Re: Объём земляных работ

Вот кажется работоспособный текст для подсчета объемов картограммы.
Всех проверок на непопадание в объекты не делал. Проверял на чертеже пример_otm02 -
я там размножил пару участков или на исходном файле.
Там зачем-то angbase=270 град?
Проверяй работу!

(DEFUN c:ob (/          I           NABOR    NN     PLO      spmr
         SUMA     TEXT     OLD_DIM    OLD_DIM     old_angb nnu
         pln      nnu1     seqend    att_name att_value
        )
        ;| 
вычисляет объем срезки\насыпи по разнице отметок и площаде фигуры 
|;
  (setq    OLD_DIM     (getvar "dimzin")
;;;    angbase - в данном чертеже он повернут на 270град, делаем 0
    old_angb (getvar "angbase")
  ) ;_ конец setq
  (setvar "angbase" 0)
;;;  рабочие обнуления
  (SETQ    nnu1 T
  ) ;_ конец SETQ

  (while nnu1
    (progn
    (prompt "\nУкажите номер участка ---> или ВВОД <Выход>")
    (setq nnu1 (nz_vybor1)        ;(ssget "_:S")
    ) ;_ конец setq
    )
    (if    nnu1 
;;;      -----------------  цикл выбора участков ------------------------------------------------------
      (progn
    (setq nnu (entget (ssname nnu1 0))
    ) ;_ конец setq


;;;  ===========; считывание указанных атрибутов OTM01 в список nabor ======================
    (prompt "\nУкажите блоки отметок ---> ")
    (setq nabor (ssget
              '((0 . "INSERT")
            (2 . "OTM01")
               )
            ) ;_ конец ssget
    ) ;_ конец setq ((sslength nabor)




    (if (and nabor nnu)
      (progn
        (setq i 0
          suma 0
        ) ;_ конец setq
        (while (setq el (ssname nabor i)) ; el -   примитив

          (setq att (entnext el))
          (setq seqend (cdr (assoc 0 (entget att))))
;;;      Цикл чтение АТРИБУТОВ
;;;                    ; пока есть атрибуты в блоке
          (while (not (eq seqend "SEQEND"))
;;;                    ; имя атрибута
        (setq att_name    (cdr (assoc 2 (entget att)))
              att_value    (cdr (assoc 1 (entget att))) ; значение
              att_value    (if att_value
                  att_value
                  " "
                ) ;_ if
        ) ;_ setq
        (If (= att_name "DELTA")
          (setq spmr (cons (atof att_value) spmr))
        ) ;_ конец If
        (setq att (entnext att)
              att_value    nil
        ) ;_ setq
        (setq seqend (cdr (assoc 0 (entget att))))
          )                ; end    while (not (eq seqend "SEQEND"))
          (setq i (1+ i)
          ) ;_ конец setq
        ) ;_ while

;;; Найдем среднее в nabor

        (setq i 0)
        (repeat (sslength nabor)
          (setq suma (+ suma (nth i spmr))
            i     (1+ i)
          ) ;_ конец setq
        ) ;_ конец repeat
;;; среднее значение отметки
        (setq suma (/ suma (sslength nabor)))

        (prompt "\nВыберите полилинию участка ---> ")
        (SETQ pln (entsel)
;;;        edata (entget (car pln))
          plo (* suma
             (VLA-GET-AREA (VLAX-ENAME->VLA-OBJECT (car pln)))
              ) ;_ конец *
        ) ;_ конец SETQ



        (command "_.TEXT"
             (polar (cdr (assoc 10 nnu))
                (/ pi -2)
                (* 1.2 (cdr (assoc 40 nnu)))
             ) ;_ конец polar
             (cdr (assoc 40 nnu))
             0
             (strcat "%%u" (rtos plo 2 1))
        ) ;_ конец command
      ) ;_ конец progn
    ) ;_ конец if (and nabor nnu)
      ) ;_ конец progn




;;;      -----------------  цикл выбора участков ------------------------------------------------------

      (progn
    (prompt "\nВы закончили работу")
      ) ;_ конец progn
    ) ;_ конец if - nnu

  )                    ; - while
  (setvar "dimzin" OLD_DIM)
  (setvar "angbase" old_angb)
  (princ)
) ;_ конец DEFUN
;;; -----------------    подпрограмма выбора TEXT примитива , если Esc - возврат nil --------------------------------
(defun nz_vybor1 (/ r)
  (vl-catch-all-apply
    '(lambda ()
       (setq r (ssget '((0 . "TEXT"))))
     ) ;_ end of lambda
  ) ;_ end of vl-catch-all-apply
  (setq    r (if r
        r
        nil
      ) ;_ конец if
  ) ;_ конец setq
) ;_ конец defun
;;; вызов
Спасибо сказали: Erema_Misha1
Post's attachments

пример_otm02.dwg 709.63 Кб, 7 скачиваний с 2019-08-11 

You don't have the permssions to download the attachments of this post.

Re: Объём земляных работ

Спасибо БОЛЬШОЕ. Всё работает. всё замечательно. Спасибо Вам за работу. А можно как-нибудь сделать, чтобы к положительным числа добавлялся + ?

Re: Объём земляных работ

Erema_Misha пишет:

А можно как-нибудь сделать, чтобы к положительным числа добавлялся + ?

Для Лиспа нет никаких проблем.
Замените 1 (одну) строку текста

Alan пишет:

            (strcat "%%u" (rtos plo 2 1))

на
         (strcat "%%u" (if (> plo 0.0) "+" "") (rtos plo 2 1))
Удачи!

Спасибо сказали: Erema_Misha1