Тема: LISP. Рисование точек с номерами по координатам из внешнего файла

Задача: Есть текстовый файл со списком координат (координаты могут быть как X,Y, так и X,Y,Z). Необходимо нарисовать точки с заданными координатами + проставить номера этих точек (первая координаты в списке - 1, вторые - 2 и т.д.)
Вариант использования: Можно быстро занести результаты полевых геодезических съемок в Акад.
Написал прогу kpblc

;; Сохранение состояния системных переменных
(defun lib:error-save-sysvar (sysvar-list)
  (foreach item sysvar-list
    (setq *kpblc-sysvar-list*
   (cons
     (list (car item) (getvar (car item)))
     *kpblc-sysvar-list*
     ) ;_ end of cons
  ) ;_ end of setq
    (if (cadr item) ; передано устанавливаемое значение
      (setvar (car item) (cadr item))
      ) ;_ end of if
    ) ;_ end of foreach
  ) ;_ end of defun
;; Восстановление состояния системных переменных
(defun lib:error-restore-sysvar ()
  (if *kpblc-sysvar-list*
    (foreach item *kpblc-sysvar-list*
      (setvar (car item) (cadr item))
      ) ;_ end of foreach
    ) ;_ end of if
  (setq *kpblc-sysvar-list* nil)
  (princ)
  ) ;_ end of defun
;; получение координат точек. Возвращает список координат
(defun lib:point-get-coord (string / x y z)
  (setq x      (atof (substr string 1 (vl-string-search "," string)))
string (substr string (+ 2 (vl-string-search "," string)) (strlen string))
y      (atof (substr string 1 (vl-string-search "," string)))
) ;_ end of setq
  (if (vl-string-search "," string)
    (setq z
   (atof
     (substr string
     (+ 2 (vl-string-search "," string))
     (strlen string)
     ) ;_ end of substr
     ) ;_ end of atof
  ) ;_ end of setq
    (setq z 0.0)
    ) ;_ end of if
  (list x y z)
  ) ;_ end of defun
;; Получение значения dxf-кода для примитива
(defun lib:ent-get-dxf-data (ent dxf)
  (cond
    ((= (type ent) 'ename) (setq ent (entget ent)))
    ((= (type ent) 'vla-object) (setq ent (vlax-vla-object->ename ent)))
    (t ent)
    ) ;_ end of cond
  (cdr (assoc dxf ent))
  ) ;_ end of defun
;; Последовательное чтение файла. Возвращает список точек
(defun lib:read-file (file-name / file_handle file_string result)
  (if (setq file_handle (open file-name "r"))
    (progn
      (while (and
       (setq file_string (read-line file_handle))
       (vl-string-search "," file_string)
       ) ;_ end of and
(setq file_string (vl-string-trim " " file_string))
(setq result (cons
       (lib:point-get-coord file_string)
       result
       ) ;_ end of cons
      ) ;_ end of setq
) ;_ end of while
      ) ;_ end of progn
    ) ;_ end of if
  (close file_handle)
  (reverse result)
  ) ;_ end of defun
;; Создание точек
;; Параметры: file-name текстовое имя файла
;; autonum автоматически нумеровать (t) или нет (nil)
;; В случае автоматической нумерации используется выравнивание
(defun _kpblc-make-points (file-name autonum      text-height  offset
   / point_list   counter   ent_list
   )
  (setq point_list
(lib:read-file file-name)
counter 0
) ;_ end of setq
  (foreach item point_list
    (setq counter (1+ counter))
    (command "_.point" item)
    (if autonum
      (progn ; Ведется автонумерация
(setq ent_list (list (cons 0 "TEXT")
     '(100 . "AcDbEntity")
     (cons 10
   (list (+ offset (car item))
(+ offset (cadr item))
(caddr item)
) ;_ end of list
   ) ;_ end of cons
     (cons 40 text_height)
     (cons 1 (itoa counter))
     '(100 . "AcDbText")
     ) ;_ end of list
      ) ;_ end of setq
(entmake ent_list)
) ;_ end of progn
      (progn ; Автонумерации нет
(command "_.dtext")
(while (/= (getvar "cmdactive") 0)
  (command pause)
  ) ;_ end of while
) ;_ end of progn
      ) ;_ end of if
    ) ;_ end of foreach
  ) ;_ end of defun
(defun c:mk-point (/ file_name _answer_ text_height offset)
  ;; Локальные функции
  (defun *error* (msg)
    (princ msg)
    (lib:error-restore-sysvar)
    ) ;_ end of defun
  ;; Конец локальных функций
  (lib:error-save-sysvar '(("osmode" 0)))
  (setq file_name (getstring "\nВведите имя файла : "))
  (initget "Да Нет Yes No _ Yes No Yes No")
  (setq _answer_
(getkword "\nВыполнять автоматическую нумерацию [Да/Нет] <Нет>? : "
   ) ;_ end of getkword
) ;_ end of setq
  (setq _answer_ (= _answer_ "Yes"))
  (if
    (= (lib:ent-get-dxf-data (tblsearch "style" (getvar "textstyle")) 40) 0.0)
     (progn
       (setq text_height
      (getreal "\nВведите высоту текста для нумерации <2.5> : ")
     ) ;_ end of setq
       (if (not text_height)
(setq text_height 2.5)
) ;_ end of if
       (setq offset (getreal "\nВведите значение смещения текста <0.0> : "))
       (if (not offset)
(setq offset 0.0)
) ;_ end of if
       ) ;_ end of progn
     (setq text_height
    (lib:ent-get-dxf-data (tblsearch "style" (getvar "textstyle")) 40)
   ) ;_ end of setq
     ) ;_ end of if
  (_kpblc-make-points file_name _answer_ text_height offset)
  (lib:error-restore-sysvar)
  ) ;_ end of defun

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> SStas
А как выглядят "результаты полевых геодезических съемок" в текстовом файле? Уж, наверное, не так:
_point
1784.321,859.000,0.000
_-TEXT
1784.321,859.000,0.000
1
_point
1784.316,852.514,34.926
_-TEXT
1784.316,852.514,34.926
2
Я так понимаю, что потом, отсортировав точки по Z, можно соединить их полилинией и получим горизонтали, а если очень сильно подумать, то можно построить и рельеф поверхности (???).
Какой-нибудь реальный фрагмент текстового файла реальной съемки можно здесь привести для проверки работы программы? А то сочинять координаты точек как-то несподручно.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Владимир Громов
Вопрос об автоматическом построении горизонталей уже тут поднимался, результат был такой: "только руками!". В принципе, можно провернуть дополнительные действия: отсортировать список по Z, сделать слои с именами "Z_<Значение_координаты>, т.е. будет слой Z_0, Z_0.05, Z_0.0051 и т.д. и раскидать по ним точки. Цвета слоев - дело десятое. И работать со слоями.
или как вариант пробовать опять-таки сортировку и делать блоки, в которые засовывать точки с одинаковыми высотными отметками. Мне, к сожалению, сегодня не удастся, скорее всего. И в принципе это уже отдельная утилита.
---
ИМХО

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> kpblc
Да, я помню. То, о чем ты говоришь, конечно же, отдельная утилита. У нас в свое время "Планикад" не пошел, потому что не было пикетов в электронном виде. Вот я и хотел посмотреть здесь, как выглядит файл, подготовленный для твоей программы. Конечно, можно проанализировать твой код и понять логику, но для меня иногда легче написать, чем разбираться в готовой программе. Программа подошла SStas'у, может он приведет фрагмент?

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Так и делалось фактически под его требования. А текстовый файлик должен быть вида

1.1,2.659,3.0
100.0,326.65,3.25
200.325,32659.689,14.365

Ну и так далее.
Пустые строки игнорируются.
Некоторые ограничения проги:
1. Проверена работа в мировой системе координат. Для пользовательских систем координат работа не проверялась.
2. Если отсутствует 3-я координата, она назначается равной 0. Без запросов и без вариантов.
3. Отсутствие второй или первой координат вызовет досрочный выход из функции.
4. Разделитель координат должен быть обязательно "," (запятая); разделитель целой и дробной частей - "." (точка).

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> kpblc
Так это просто список координат точек. А вот как он получается? Не вручную же его записывают в текстовый файл, сколько ошибок можно налепить.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Ну это уже явно не могу решить - там вариантов тьма.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Есть электронный тахеометр, но нет специализированного софта для него и на компе стоит Autodesk Map, а не Land, так что напрямую перегонять результаты замеров не получается.
С тахеометра перегоняю через Гипертерминал, далее в Word, где простенький макрос написан, который удаляет/заемняет символы и в итоге выдает такой список. Далее в Автокад =)
Впрочем, у нас ещё и не электронный тахеометр есть, так что можно даже на поле в блокнотик записывать координаты, а потом в файл набивать.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> SStas
Енто не есть гуд - масса лишней работы имхо. Оба варианта в принципе в конце концов формируется текстовый файлик. Вот его бы исходник поглядеть было бы интересно - тогда есть вариант вообще все читать лиспом.
P.S. Эдуард сказал, что тут где-то была уже такая прога, искать только надо...

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Когда работал на строительстве автодорог, был у нас какой-то дешевый тотал-стейшн давал такой файл:

1         ,1         ,315775.460,307530.190,1034.383
2         ,2         ,315775.482,307530.199,1034.379
3         ,3         ,315873.134,307501.087,1029.727
...

Читал его без преобразований с лиспа через "substr".

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> che
Так там в конце еще до дури может инфы идти... Ее-то отрубать надо будет. В общем, полный исходник глянуть не помешало бы имхо.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> kpblc
А дело в том, что там разные виды памяти и разные виды работ бывают, поэтому то, что получаается на выходе из тахеомтра может различаться.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Ну и что? Достаточно по 2-3 строчки, характерных (т.е. строки начала файла - там наверняка идут какие-то комментарии, строки собственно данных, строки окончания файла). Можно попробовать будет.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

kpblc переделал прогу, чтобы она воспринимала данные в формате rec500 от тахеометров Trimble серии 3300
(Точно работает с Trimble 3305, при памяти MEM/3)
Если кому нужна такая заточка проги ? пишите мне на мыло или сюда.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

А я пошёл по другому пути, хотя задача стояла анологичная.Координаты в виде (? тчк.,X,Y,Z ) скидываю в Ексель, как это сделать из Вашего формата полагаю что каждый сумеет сам. В Екселе написал функции , и через SCRIPT скидываю это всё  в Акад.
В Акаде получаем - ?тчк. в виде однострочного текста по координатам X,Y, отметки в том же виде по координатам X,Y,Z, сами точки в виде круга 2D по координатам X,Y с заданым диаметром (для удобства рисовки ситуации), и POINT по координатам X,Y,Z ( можно строить модель и горизонтали).И это всё на разных слоях.
Кого интерисует мой метод - охотно поделюсь.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Игорь
Вместо рисования окружностей можно воспользоваться программной установкой значений системных переменных pdmode и pdsize, или с ком.строки дать команду _.ddptype и выбрать там.
Лично меня интересует вопрос со слоями. Что здесь имелось в виду? Программно в лиспе можно сделать очень много, главное - задачу поставить.
Постарайтесь понять меня правильно - я не ругаю Ваш метод, просто лично мне лень лишний раз запускать дополнительные приложения, если можно обойтись одной командой.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Игорь
Изначально делал примерно так же, только без окружностей. А теперь сабжем ? быстрее получается ;)

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> kpblc
Ну я же написал "POINT по координатам X,Y,Z".
Копирую в Екселе колонку с координатами,в Акаде даю команду POINT и вставляю в текстовую строку.
Значения pdmode и pdsize выставляю по умолчанию как мне угодно.А окржности делаю для удобства рисовки ситуации,затем слой с окружностями и номерами точек, после полной обработки, удаляю за ненадобностью.
А вот насчёт Лиспа я с Вами согласен.Главное чтобы задача стояла.Изучение Лиспа у меня на начальной стадии, так как задач не было.А вот и она: нужно однострочный текст в виде отметок(напр.303.25..303.47) из Акада забросить в Ексель по координатам X,Y а значение текста по Z.Я что-то такое сотворил,но за отсутствием глубоких знаний никак не могу доделать.Помогите уж пожалуйста.
(defun tmp1 (  )
(setq nm (getvar "dwgname"))        ;
(setq lnm (strlen nm))            ;
(setq llnm (- lnm 3))            ;
(setq nam (substr nm 1 llnm))        ;
(setq name (strcat nam "csv"))        ;
(setq opf (open name "w"))        ;
;;;----------------------------------------------------------------------------
(setq list_rad '())  ;создает список             ;
(setq nab_cir (ssget "_x" (list (cons 0 "TEXT") (cons 8 "0")))) ;создает набор
(setq i          -1
      nab_len (sslength nab_cir)
);создает i по набору                    ;
(repeat    nab_len
  (setq i (1+ i)) ;создает i            ;
  (setq cirlist (entget (ssname nab_cir i))) ;создает cirlist
  (setq radcir (cdr (assoc 1 cirlist)))    ;создает radcir
  (setq cencir (cdr (assoc 10 cirlist))) ;создает cencir
  (setq cen_ccr (rtos (nth 0 cencir) 2 3)) ;создает cen_ccr
  (setq rad_ccr  (rtos (nth 1 cencir) 2 3)) ;создает rad_ccr
  (setq    list_rad (strcat rad_ccr "\t" cen_ccr "\t" radcir))
    (write-line list_rad opf)
  );conec                    ;
(close opf)
(alert ( strcat "Файл  " name "  создан в текущей папке"))
(princ)
)

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Есть предложение общаться по почте - порежут ветку.
Кстати, ко мне, если можно, на "ты".

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> SStas
Что-то я не понял что такое  "сабжем",извините уж за неграмотность.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Игорь
Сабж = subj = subject - тема, объект топика и т.п.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> kpblc
Ёще раз извините за неграмотность, а subj это команда в Акаде или программа?
Если можно то поподробней.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Игорь
см. почту

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

> Игорь
Это жаргон, pancake, ^~.

Re: LISP. Рисование точек с номерами по координатам из внешнего файла

Владимир Громов пишет:

Это жаргон, pancake, ^~.

а это что еще за КАКА такая?