Extract xy-coordinates of multiple plines and add these to a notepad-file?

Extract xy-coordinates of multiple plines and add these to a notepad-file?

Anonymous
Not applicable
1,617 Views
7 Replies
Message 1 of 8

Extract xy-coordinates of multiple plines and add these to a notepad-file?

Anonymous
Not applicable

Hi,

 

(auto/visual)-LISP noob here 🙂
Could somebody take a look at the code below and point me in the right direction, please?
Any help would be much appreciated, I would be very grateful 🙂


I'm trying to create a (auto/visual)-LISP that does the following:
- Make a selectionset of all P-lines in modelspace in layers X_050, X_CU50 and X_TU050
- Retrieve the XY-coordinates of these polylines
- Create a notepad-file and paste these coordinates in the following manner:

"start-text"+"start-pline" + "XY-coordinates pline1" + "end-pline" + "start-pline" + "XY-coordinates pline2" + "end-pline" + ... + "end-text"
(the "start-text", "start-pline", "end-pline" and "end-text" will be replaced by strings)

-Save this notepad-file as a .gml, in a folder specified by 'path_leg'

 

FYI:
Should be able to handle between 1 and 100 plines.

Exporting as a GML via MAPEXPORT doesnt seem to be an option, because the strings in need to use as "start-text","start-pline"... are to specific.

Tried using Google for hours to come up with a solution. I found much useful info, but haven't been able to combine it in my specific case.

 

This is what I have so far:

 

 

(defun c:test1 ()

(setq n1 (- (strlen (getvar "dwgprefix")) 4));;look for the current DWG-folder and remove the last 4 characters

(setq path_leg (strcat  (substr (getvar "dwgprefix") 1 n1) "GIP\\"));;change the above path and add a "GIP"-folder, assign to 'path_leg'

(vl-mkdir path_leg);;create the GIP-folder

(setq fn1 (vl-filename-base (getvar "dwgname")));; assign the current DWG-name to 'fn1'

(setq gmlfile (open (getfiled fn1 path_leg "gml" 1) "w"));;create textfile with name stored in 'fn1' in the new GIP-folder with extention .gml

(write-line "start-text" gmlfile);; write "start-text" at the start of the GML-file

(setq ss1 (ssget x (0 . "*LINE")(8 . "X_050")(8 . "X_TU050")(8 . "X_CU050")(67 . 0)));;make a selectionset of the plines in modelspace in the given layers


THANK YOU TO ANYONE WHO REPLIES 🙂

 

0 Likes
Accepted solutions (1)
1,618 Views
7 Replies
Replies (7)
Message 2 of 8

Ranjit_Singh
Advisor
Advisor

Hi @Anonymous. Welcome to the forums. Since you know LISP, I will leave the formatting of co-ordinates upto you. Try something like this for example

;;Ranjit Singh
;;7/13/17
(defun c:somefunc  (/ file1)
  (setq file1 (open (getfiled "Specify filename and location" "" "gml" 1) "w"))
  (mapcar '(lambda (x)
             (write-line (strcat "start-text start-pline "
                                 (vl-princ-to-string (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x)))))))
                                 " end-pline")
                         file1))
          (vl-remove-if 'listp
                        (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "lwpolyline") (8 . "X_050,X_CU50,X_TU050")))))))
  (close file1)
  (princ))

You can rpelace

(getfiled "Specify filename and location" "" "gml" 1)
with your above code to make the directory and pass the file path. Let me know if you need any help with that. Good luck.
Message 3 of 8

pbejse
Mentor
Mentor

@Anonymous_001_ wrote:
...

 

"start-text"+"start-pline" + "XY-coordinates pline1" + "end-pline" + "start-pline" + "XY-coordinates pline2" + "end-pline" + ... + "end-text"
(the "start-text", "start-pline", "end-pline" and "end-text" will be replaced by strings)

 

-Save this notepad-file as a .gml, in a folder specified by 'path_leg'

 


Forgive my ignorance but i'm  curious about .gml file format, Is there a specific format for the coordinates to appear on the gml file? 

will that be ( ( x1  y1 ) ( x2 y2 ) ( x3 y3 ) ) or (  x1 y1 x2 y2 x3 y3 ) or even ( x y z ) ?

 

0 Likes
Message 4 of 8

Anonymous
Not applicable

Hi,

 

First and foremost: Thank you VERY much, Ranjit! This has helped me enormously!

I've modified your above code a little bit:

 

(setq gmlfile (open (getfiled fn1 path_leg "gml" 1) "w"));;create gml-file
  (write-line "start-text" gmlfile);;start with "start-text"
  (mapcar '(lambda (x)
             (write-line (strcat "start-pline"
                                 (vl-princ-to-string (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x)))))))
                                 "end-pline");;"start-pline" before each pline and after each pline "end-pline"
                         gmlfile))
          (vl-remove-if 'listp
                        (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "lwpolyline") (8 . "X_050,X_CU050,X_TU050")))))));;selectionset
  (write-line "end-text" gmlfile);;end with "end-text"
(close gmlfile)
  (princ))

 


Right now, a test-output of the gml-file (made from 2 polylines) looks like this:

 

start-text
start-pline((110979.0 209492.0) (111018.0 209449.0))end-pline
start-pline((110925.0 209525.0) (110943.0 209563.0) (111136.0 209404.0) (111125.0 209375.0) (111098.0 209377.0))end-pline
end-text

 


However, I have 2 more questions:

 

1)
Does anyone have an idea why no decimal values are extracted from the polylines?

If I use LIST on the first polyline, AutoCAD returns this:

LWPOLYLINE  Layer: "X_CU050"
                            Space: Model space
                   Handle = 390
              Open
    Constant width    0.0000
              area   0.0000
            length   58.1003

          at point  X=110978.9704  Y=209491.5112  Z=   0.0000
          at point  X=111018.3604  Y=209448.8020  Z=   0.0000

 

So it seems that these values are indeed present, but aren't copied to the file.
I think it may be a settings issue?
I've already checked UNITS, and that is set to 0.0000

I also found this: (don't know whether it is intended for this issue?)

Don't be misled by what AutoCAD displays by default. On any AutoLisp
 symbol that is a 'Real, use (rtos symbol 2 10) to see its actual value as a
 string to 10 decimal places.

 For a list of reals, you could create a function, say...
 (defun rtos210 (n)(rtos n 2 10))
 and then (mapcar 'rtos210 basept)

But I haven't found a way to insert this correctly...

2)
Could somebody please help me how to remove the parentheses? The formatting is otherwise perfect, I just need to be able to dump all the "(" and ")" so it would look something like this: (This question probably answers pbejse's question)

 

start-text
start-pline110979.0 209492.0 111018.0 209449.0end-pline
...

I've tried using something like this in different ways, but it never works for me: (I might be using it wrong?)

 

(setq lst '("some text"))
 (car lst) returns "some text"

 


THANK YOU TO ANYONE WHO REPLIES, ANY HELP IS MUCH APPRECIATED! 🙂

0 Likes
Message 5 of 8

pbejse
Mentor
Mentor

@Anonymous wrote:

Hi,

  

start-text
start-pline110979.0 209492.0 111018.0 209449.0end-pline
...

I've tried using something like this in different ways, but it never works for me: (I might be using it wrong?)

 


 

Try and change this

 

(strcat
  "start-pline"
  (vl-princ-to-string
    (reverse
      (cdr
	(reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x))))
      )
    )
  )
  "end-pline"
)

 

To

 

(strcat	"start-pline"
	(substr	(setq strcoordinates
		       (vl-princ-to-string
			 (vlax-get (vlax-ename->vla-object x)
				   'Coordinates
			 )
		       )
		)
		2
		(- (Strlen strcoordinates) 2)
	)
	"end-pline"
)

 

I would've coded the whole thing  differently though .

 

HTH 

 

Message 6 of 8

Ranjit_Singh
Advisor
Advisor
Accepted solution

AutoCAD is precise upto 14 decimals (or something around that) and you can set the precision using rtos. Replace

(vl-princ-to-string (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x)))))))

with

 

(mapcar '(lambda (x) (rtos x 2 2)) (apply 'append (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x))))))))

Note the (rtos x 2 2). The last 2 denotes the number of precision you want to report. Your enveloping mapcar will now look like this

 

(mapcar '(lambda (x)
            (write-line (strcat "start-pline"
                                (mapcar '(lambda (x) (rtos x 2 2))
                                        (apply 'append (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x))))))))
                                "end-pline")
                        ;;"start-pline" before each pline and after each pline "end-pline"
                        gmlfile))
          (vl-remove-if 'listp
                        (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "lwpolyline") (8 . "X_050,X_CU050,X_TU050")))))))

 EDIT: Completely forgot that we need spaces between the co-ordinates. Try below.

(mapcar '(lambda (x)
          (write-line (strcat "start-pline"
                              (vl-string-right-trim " "
                                                    (apply 'strcat
                                                           (mapcar '(lambda (x) (strcat (rtos x 2 2) " "))
                                                                   (apply 'append (reverse (cdr (reverse (vl-remove-if-not 'listp (mapcar 'cdr (entget x))))))))))
                              "end-pline")
                      ;;"start-pline" before each pline and after each pline "end-pline"
                      gmlfile))
        (vl-remove-if 'listp
                      (mapcar 'cadr (ssnamex (ssget "_x" '((0 . "lwpolyline") (8 . "X_050,X_CU050,X_TU050")))))))
Message 7 of 8

serban_nicolau
Community Visitor
Community Visitor
(mapcar 'rtos210 (assoc 10 ent))

ent being the list

0 Likes
Message 8 of 8

eescobar55C7H
Observer
Observer

Not my lisp but this will give you an output of x,y,z coordinates of a single pline

maybe you could adjust it to do exactly what you want

 

0 Likes