AutoLISP for polyline label with Layer Name and Length

AutoLISP for polyline label with Layer Name and Length

sunethW86GH
Explorer Explorer
1,076 Views
11 Replies
Message 1 of 12

AutoLISP for polyline label with Layer Name and Length

sunethW86GH
Explorer
Explorer

I need to make a label like the below image
offset a selected polyline, add a text label with the layer name and polyline length, and draw perpendicular lines at the start and end points of the new polyline.
Does anybody have AutoLisp for that?

Screenshot 2024-08-12 225120.png

0 Likes
Accepted solutions (1)
1,077 Views
11 Replies
Replies (11)
Message 2 of 12

Sea-Haven
Mentor
Mentor

Maybe the country I live in Australia never seen drainage shown like that ? Could be done better if you must have a diagram like this. take plines and spread and scale, similar approach to survey field notes. 

 

Fo real comments need a dwg not a image.

Message 3 of 12

sunethW86GH
Explorer
Explorer

Thank your reply I looking for lisp program. and i wrote lips but it not working correctly

 

(defun c:QA ()
(setq pline (car (entsel "\nSelect the polyline to offset: ")))
(if (not pline)
(princ "\nNo polyline selected. Exiting.")
(progn
;(setq offset-point (getpoint "\nSpecify the point to offset by picking: "))
(setq offset-distance 100.0) ; Offset distance (0.1 meters outside)
(setq layer-name (cdr (assoc 8 (entget pline))))
(setq pline-length (vlax-curve-getDistAtParam pline (vlax-curve-getEndParam pline)))
(setq text-content (strcat layer-name ", L= " (rtos pline-length 2 2)))

; Offset the polyline
(command "_.OFFSET" offset-distance pline pause "")

;; Get the newly created offset polyline
(setq pline-new (entlast))
(setq text-pos (vlax-curve-getpointatparam pline-new (/ (vlax-curve-getendparam pline-new) 2))) ; Middle point of polyline
(setq text-height 2.5) ; Text height (adjust as needed)

; Add text with layer name and polyline length
(command "_.text" text-pos text-height 0 text-content)

; Draw perpendicular lines at start and end points
(setq start-point-pline (vlax-curve-getstartpoint pline))
(setq end-point-pline (vlax-curve-getendpoint pline))
(setq start-point-pline-new (vlax-curve-getstartpoint pline-new))
(setq end-point-pline-new (vlax-curve-getendpoint pline-new))
(command "_.line" start-point-pline-new (polar start-point-pline-new (angle start-point-pline-new start-point-pline) 10.00) "")
(command "_.line" end-point-pline-new (polar end-point-pline-new (angle end-point-pline-new end-point-pline) 10.00) "")
)
)
(princ)
)

0 Likes
Message 4 of 12

Moshe-A
Mentor
Mentor
Accepted solution

@sunethW86GH  hi,

 

Tell you the truth, looking at your picture for some hours i did not understand what you want? then i tried your lisp and it work so what's the op wants? what is not working here? why the offset? 

 

eventually it came out to this...

check my version (totally base on your) but has some improvement

 

1. you can select a pline or line

2. all inputs is done at top

3. the main program is encapsulate in (while) so if an 'error' occur at the test expr, the program is exit clean.

4. the content position and angle is determined by 2 local function (text_direction) and (text_angle) that puts the

    content above the pline at readable angle.

5. finally, the whole 'thing' is done with pline and the offset is erased.

 

hope you'll like it 😀

 

enjoy,

Moshe

 

 

(defun c:QA (/ text_direction readable_angle ; local functions
	       OFFSET-DISTANCE PERPEND-LENG savLayer ss pline offset-side layer-name pline-length text-content pline-new text-pos text-height
	       start-point-pline end-point-pline start-point-pline-new end-point-pline-new pline-angle-new perp-end-1 perp-end-2)

 (defun text_direction (a)
  (if (and (> a (* pi 0.5)) (< a (* pi 1.5)))
   (- a (/ pi 2))
   (+ a (/ pi 2))
  )
 ); text_direction
 
 (defun text_angle (a)
  (if (and (> a (* pi 0.5)) (< a (* pi 1.5)))
   (+ a pi)
   a
  )
 ); readable_angle


 ; here start c:qa
 (setvar "cmdecho" 0)
 (command "._undo" "_begin")

 ; define some constants
 (setq OFFSET-DISTANCE 100.0) ; Offset distance (0.1 meters outside)
 (setq PERPEND-LENG 10.0)
  
 (setq savLayer (getvar "clayer"))
  
 (while (and
         (not (prompt "\nPick polyline to offset: "))
         (setq ss (ssget ":s:e+." '((0 . "line,lwpolyline"))))
         (setq pline (ssname ss 0))
         (not (redraw pline 3))
         (setq offset-side (getpoint "\nSpecify point on side to offset: "))
       )
  (if (/= (setq layer-name (cdr (assoc 8 (entget pline)))) (getvar "clayer"))
   (setvar "clayer" layer-name)
  )
   
  (setq pline-length (vlax-curve-getDistAtParam pline (vlax-curve-getEndParam pline)))
  (setq text-content (strcat layer-name ", L= " (rtos pline-length 2 2)))
  
  (command "_.OFFSET"  OFFSET-DISTANCE pline offset-side "")

  (setq pline-new (entlast))
  (setq text-pos (vlax-curve-getpointatparam pline-new (/ (vlax-curve-getendparam pline-new) 2))) ; Middle point of polyline
  (setq text-height 2.5) ; Text height (adjust as needed)
  
  (setq start-point-pline (vlax-curve-getstartpoint pline))
  (setq end-point-pline   (vlax-curve-getendpoint pline))
  
  (setq start-point-pline-new (vlax-curve-getstartpoint pline-new))
  (setq end-point-pline-new   (vlax-curve-getendpoint pline-new))
  (setq pline-angle-new (angle start-point-pline-new end-point-pline-new))

  (command "._text" "_Middle" (polar text-pos (text_direction pline-angle-new) text-height)
	              text-height (angtos (text_angle pline-angle-new) 0 4) text-content)

  (setq perp-end-1 (polar start-point-pline-new (angle start-point-pline-new start-point-pline) PERPEND-LENG))
  (setq perp-end-2 (polar end-point-pline-new (angle end-point-pline-new end-point-pline) PERPEND-LENG))

  (command "._pline" "_None" perp-end-1 "_width" 0 0 "_None" start-point-pline-new "_None" end-point-pline-new "_None" perp-end-2 "")
  (entdel pline-new) ; delete the offset
 ); while

 (setvar "clayer" savLayer)

 (command "._undo" "_end")
 (setvar "cmdecho" 1)
 
 (princ)
); c:QA

 

 

 

 

 

 

Message 5 of 12

АлексЮстасу
Advisor
Advisor

Hi, sunethW86GH


You could put it this way:
1. For many selected polylines, do OFFSET or COPY.
2. Immediately for all these polylines make inscriptions - XDLabel (fas).
3. Also make cross Lines - XDPoint (fas).

XDLABEL_CREATE command - create inscriptions. In the first window double click on the Layer property. In the second window select NEAR, SINGLE, CENTER, define Delta Y - distance from polylines and other necessary parameters and Ok. Then in the first window double click on the Length 2D property, and in the second window set parameters and Ok.
In the first window select both defined parameters and Ok.

XDPOINT_CREATE command - create Lines. In the program window select Type of point objects LINE, select ON, SINGLE, START, define Relative Rotation 90 or 270 and Line length. Press ^ ^ Add.
Give another parameter name, select ON, SINGLE, END, press ^ ^ Add.
Select the names of the created parameters in the upper list and Ok.

 

The created inscriptions and Lines will be linked to their base objects. If these polylines are shifted or lengths, layers, or shifted, inscriptions and Lines are changed, their relative position and inscriptions content can be restored with the XDLABEL_UPDATE and XDPOINT_UPDATE commands.

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help

Message 6 of 12

sunethW86GH
Explorer
Explorer

HI Moshe-A,

I appreciate your help very much
That's exactly the kind of AutoLISP I was looking for
It works fine for me
but The text position can sometimes be confusing
My sincere thanks go out to you once again for your time and effort

 

0 Likes
Message 7 of 12

sunethW86GH
Explorer
Explorer

Hi,

I appreciate your help
I will check that tool

0 Likes
Message 8 of 12

Moshe-A
Mentor
Mentor

@sunethW86GH ,

 


@sunethW86GH wrote:

HI Moshe-A,

I appreciate your help very much
That's exactly the kind of AutoLISP I was looking for
It works fine for me
but The text position can sometimes be confusing
My sincere thanks go out to you once again for your time and effort

 


thank you, glad i could helped 😀

 

yes you are right, to insert a text at readable angle is a bit challange and i overcome it with (text_angle) function.

you did not answer my question about the need to offset the pline? cause this all can be done without the need to offset.

 

Moshe

 

 

 

Message 9 of 12

sunethW86GH
Explorer
Explorer
Dear Moshe
My road plan drawings have several types of curbs and drains with separate layers
I want to label all of them like in my image
so then I tried to write LISP
There is no need to offset polyline
just I need the label of like in my image
thank you

Suneth
0 Likes
Message 10 of 12

Moshe-A
Mentor
Mentor

So now the question is:

Does the legs (the short lines of 10 units) are always at ooposite side of the content?

 

0 Likes
Message 11 of 12

sunethW86GH
Explorer
Explorer
It doesn't matter which side the content is on
I think it is better to opposite side
0 Likes
Message 12 of 12

АлексЮстасу
Advisor
Advisor

... It seems to me that in your case it is better to make not offset, but copy, so that the lengths of rendered and original lines are the same. To avoid any misunderstandings.
And, if you are working in basic AutoCAD, you could use XData for additional descriptive information (depth, width, material, etc.). The tools to use them are in my link. Or use Map/Civil - they have Object Data, Property Sets for descriptive data, and many other features.

 


-- Alexander, private person, pacifist, english only with translator 🙂 --

Object-modeling _ odclass-odedit.com _ Help