Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

text value from a specific location (x,y)

15 REPLIES 15
Reply
Message 1 of 16
framednlv
1322 Views, 15 Replies

text value from a specific location (x,y)

I need help getting a text value from a specific coordinate (x,y). All I can find is "setq txt (car (entsel "Pick Text")))". I will aslo need to set a value (",") if there is no text at the location. I have hundreds of files I need to do so I don't want to manually enter anything.



Any help would be great,
Chris
15 REPLIES 15
Message 2 of 16
Kent1Cooper
in reply to: framednlv

Is that specific coordinate location always the *insertion point* of the Text? If it is, and the Z coordinate is always 0, you could probably do something like this:

{code}

(setq txt
(if (setq txtsel (ssget "X" '((0 . "TEXT") (10 yourx youry 0.0))))
(cdr (assoc 1 (entget (ssname txtsel 0))))
","
); end if
); end setq

{code}

Replace 'yourx' and 'youry' with the values of the coordinate. If there happen to be more than one piece of Text with that same insertion point, it will only extract the text content from one of them.

--
Kent Cooper
Kent Cooper, AIA
Message 3 of 16
framednlv
in reply to: framednlv

Yes, the insertion point is the coordinate I'm using.



I ran yours on one of the files I'm going to work on. I keep getting "," as a result even thou the text is at 0,0. Here is what I ran:



(setq txt

(if (setq txtsel (ssget "X" '((0 . "TEXT") (10 0.0 0.0 0.0))))

(cdr (assoc 1 (entget (ssname txtsel 0))))

","

); end if

); end setq

(PRINT TXT)

The results are ",".

Then I ran:

(entget (car (entsel)))



Select object: ((-1 . <Entity name: -406795e0>) (0 . "TEXT") (330 . <Entity name: -4015b308>) (5 . "180C") (100 . "AcDbEntity") (67 . 0) (410 . "Model") (8. "TEXT") (100 . "AcDbText") (10 -2.44799 -3.67198 0.0) (40 . 7.34396) (1 . "N") (50 . 0.0) (41 . 1.0) (51 . 0.0) (7 . "PNL-SI") (71 . 0) (72 . 4) (11 0.0 0.0 0.0) (210 0.0 0.0 1.0) (100 . "AcDbText") (73 . 0))





The location is 0,0 and the results are different. I'm not sure what is going on. I started a new drawing and typed in dtext at 0,0 and the results were correct.





Chris



Edited by: framednlv on Mar 27, 2009 9:15 PM Edited by: framednlv on Mar 27, 2009 9:16 PM
Message 4 of 16
framednlv
in reply to: framednlv

I don't know what happened to the forum editor, but it really does some stange formatting and I couldn't find any code tages

The justification of the text at 0,0 was middle. As soon as I changed it to left it worked fine. Will I need to change all the text justification before I run my program or is there a different way to do this?


Thanks,
Chris
Message 5 of 16
curmudgeon
in reply to: framednlv

I am confused at using (ssget "_X" ) with a point location. Just does not feel right.

You want to select text blind? What if there is a space at your selection point?

I am not so certain it would be reliable, but I have been wrong before. I think I might try creating a points list from the point that would represent a small polygon centered on your pick point, and pass that to (ssget "_CP" pnt_lst '((0. "TEXT,MTEXT ) (8 . "only_the","layers I","want")))

You would have to decide the size and shape of the crossing box.

Selection sets based on WP and CP are really cool, as is F. I am working on architectural plans, and I have a polyline describing a room. I can select everything IN the room with a points list from the polyline and CP.

cool?

ooh, and remember when you are selecting text entities, 10 is not always the same as 11 based on too many variables for me to keep straight. If the justification is bottom left, as I seem to recall, 11 does not get set, and you may have nothing to grab at 11. Stuff like that is why I would hesitate to grab text by a specific point location. Edited by: curmudgeon on Mar 28, 2009 10:59 AM
Message 6 of 16
framednlv
in reply to: framednlv

A couple more questions.
How can I setq for (10 yourx youry 0.0) and how can I change it from yourx to yourx + 1

I tried:
(setq yourx 0.0)
(setq youry 0.0)
(setq DN (getvar "DWGNAME"))
(setq DP (getvar "DWGPREFIX"))
(substr DN 1 (- (strlen DN) 4))
(setq filename (strcat (substr DN 1 (- (strlen DN) 4)) ".csv" ))
(setq txt
(if (setq txtsel (ssget "X" '((0 . "TEXT") (10 yourx youry 0.0))))
(cdr (assoc 1 (entget (ssname txtsel 0))))
","
); end if
); end setq


(setq file (open filename "w"))
(write-line txt file)
(close file)


How do I post the code?

Curmudgeon,
I want to pick specific locations and if nill then I need to use ",". I might look at crossing as it could help if the text isn't where it should be. Could you post how to set the list for using a crossing. Perhaps how to modify the list.

Thanks,
Chirs
Message 7 of 16
framednlv
in reply to: framednlv

Delete, post showed up twice

Edited by: framednlv on Mar 28, 2009 8:02 PM Edited by: framednlv on Mar 28, 2009 8:03 PM
Message 8 of 16
curmudgeon
in reply to: framednlv

back now, if you haven't solved it yet.

as I read your results from (entget (car (entsel)))) , your dxf 10 is -2,-3, and your text was "N" and your dxf 11 was 0,0.
this is where the dxf code is more complicated, I think that piece of text your routine is failing to grab is middle center justified, and that is the 11 code. the 10 code is where the insertion point would be if it were lower left justified but appeared in the same location on the screen.

I seem to remember that lower left is default, and that is the dxf 10. 11 is only added to a text entity for other than default justification. not being able to see your screen, here is what I would try.

I assume this piece of text is always in the same place in different drawings. if not, this would still be a starting point.
(setq my_text (ssget "_CP" '((-3 -4)(3 -4)(3 4)(-3 4)) '((0 . "TEXT")(8. "TEXT")))

this is of the form (ssget "_WP" pt_list '((0 . "LINE") (62 . 5))) like in the Vlisp help file for ssget except it filters for text entities on the layer "text", and uses a window selection instead of a crossing selection.

I picked '((-3 -4)(3 -4)(3 4)(-3 4)) for a point list because it would define a rectangle that should include (10 -2.44799 -3.67198 0.0) .
I think you could
(setq my_text (ssget "_C" '((-3 -4)(3 4)) '((0 . "TEXT")(8. "TEXT")))
and get the same results. that should be a crossing selection like responding "C" to a standard prompt.

then there is the what to do with the what you get, or failed to get.

I guess it is good form to have kind of standard names for selections sets so that one remembers they are selections sets and not lists or integers, or things that get manipulated directly. so

(setq ss1 (ssget "_CP" '((-3 -4)(3 -4)(3 4)(-3 4)) '((0 . "TEXT")(8. "TEXT")))

and then you could
(if ss1
(setq my_text (cdr (assoc 1 (entget (ssname ss1 0)))))
(setq my_text ",")
)

ssname returns the first, and only item in the selection to
enget which gets the association list for the entity ,
which associates dxf code 1 with the text content dotted pair and
cdr is that dotted pair minus the first item.
"N"

inside out, that is the then to the if statement and the else would be ","

good?

to make this look in places other than 0,0,0 all you would need to do would be to pass a point location other than the origin to the routine.

one thought, and then I think I will get back to my project. you might need to , in the program, set your UCS to world first. I forget from time to time, but some lisp is dependent on the current UCS, and some is dependent on whether entities are actually visible. some depend on your pick box, so it would be possible to be zoomed in too close for some selection methods to reliably select intermittent entities such as text or lines with other than continuous line type.

regards,

roy Edited by: curmudgeon on Mar 28, 2009 9:06 PM
Message 9 of 16
H.vanZeeland
in reply to: framednlv

Hi,

Try this

This search the text between a given point Pt - an + 0.1

(defun c:test ( / Pt miPt maPt DN DP filename txt txtsel elist)

(setq Pt '(0.0 0.0 0.0)); change this for other locations

(setq miPt (mapcar '- Pt '(0.1 0.1 0.1)))

(setq maPt (mapcar '+ Pt '(0.1 0.1 0.1)))

(setq DN (getvar "DWGNAME"))

(setq DP (getvar "DWGPREFIX"))

(setq filename (strcat DP (substr DN 1 (- (strlen DN) 4)) ".csv" ))

(setq txtsel (ssget "X" (list '(0 . "TEXT")'(-4 . "<or")

'(-4 . "<and")'(-4 . ">=,>=,>=")(cons 10 miPt) '(-4 . "<=,<=,<=")(cons 10 maPt)'(72 . 0)'(-4 . "and>")

'(-4 . "<and")'(-4 . ">=,>=,>=")(cons 11 miPt) '(-4 . "<=,<=,<=")(cons 11 maPt)'(-4 . "/=")'(72 . 0)'(-4 . "and>")

'(-4 . "or>"))))

(setq file (open filename "w"))

(if txtsel

(repeat (sslength txtsel)

(write-line (cdr (assoc 1 (entget (ssname txtsel 0)))) file)

(ssdel (ssname txtsel 0) txtsel)

)

(write-line "," file)

);end if

(close file)

(princ)

)

Hope this wil help

Cheers

Harrie Edited by: h.vanzeeland on Mar 29, 2009 10:23 AM
Message 10 of 16
Kent1Cooper
in reply to: framednlv

It slipped my mind again that text insertion points are inconsistent in AutoCAD, which I wish they would fix. The 10 code is the left end of the base line, regardless of the justification. When the justification is Left, that is also the insertion point. With any other justification, the insertion point (what you would get with Osnap Insert) is stored in the 11 slot in the entity data; that is always 0,0,0 for Left-justified text, regardless of its location.

If it's always middle-justified, you can just change the 10 to 11 -- no need to change the text's justification. If the justification would vary, you would need to get more sophisticated.

--
Kent Cooper
Kent Cooper, AIA
Message 11 of 16
Kent1Cooper
in reply to: framednlv

Using the X option with insertion-point filtering is just saying "find me whatever piece of text in this drawing has its insertion point at this location." It's not a point location as though you picked there on-screen, but an element of the entity data.

The what-if-there-is-a-space question is exactly why it's probably better to filter by insertion point, since the OP seems to know what the insertion point will always be. It doesn't depend on there being some actual element of the text graphically at that location, the way C or W or CP or WP or F selection would.

You're right about the variability of 10 & 11 codes in Text entity data, but it's not quite as inscrutable as you make it sound -- see another reply of mine above.

--
Kent Cooper


curmudgeon wrote:

I am confused at using (ssget "_X" ) with a point location. Just does not feel right.

You want to select text blind? What if there is a space at your selection point?
....
Kent Cooper, AIA
Message 12 of 16
Kent1Cooper
in reply to: framednlv

When I said you should replace 'yourx' and 'youry' with the coordinates of the known insertion point, I meant literally replace, rather than set to variables and use those variable names. When using point lists in (ssget) filtering, you need to use plain values *without* variables, if they're in a plain unevaluated list with the apostrophe at the beginning, like this [changing the 10 to 11 as in another reply]:

(setq txtsel (ssget "X" '((0 . "TEXT") (11 0.0 0.0 0.0))))

or if you're setting variables that will need to be *evaluated*, you need to use the (list) command explicitly, like this:

(setq txtsel (ssget "X" (list '(0 . "TEXT") (list 11 yourx youry 0.0))))

[The '(0 . "TEXT") still gets the apostrophe, because that inner list doesn't need evaluation -- you know the expected values exactly.]

If you do it the latter way, you can easily throw in another evaluation, to get to yourx + 1:

(setq txtsel (ssget "X" (list '(0 . "TEXT") (list 11 (1+ yourx) youry 0.0))))

--
Kent Cooper


framednlv wrote:
....
How can I setq for (10 yourx youry 0.0) and how can I change it from yourx to yourx + 1

I tried:
(setq yourx 0.0)
(setq youry 0.0)
....
(setq txt
(if (setq txtsel (ssget "X" '((0 . "TEXT") (10 yourx youry 0.0))))
(cdr (assoc 1 (entget (ssname txtsel 0))))
","
); end if
); end setq
....
Kent Cooper, AIA
Message 13 of 16
framednlv
in reply to: framednlv

Thanks Everyone,

I got cought up trying to use parts of everyones example with out reading exactly what what going on.

I found that this is working just fine:
{code}(setq lcode
(if (setq txtsel (ssget "_f" '((28.341 522.674)( 37.372 522.674 )) '((0 . "TEXT") )))
(cdr (assoc 1 (entget (ssname txtsel 0))))
","
); end if
); end setq{code}

What I would like to do is set my Y value and use something like this:
{code}
(setq Yline '(522.674))
(setq ltrip
(if (setq txtsel (ssget "_f" '((43.378 Yline)( 57.551 Yline )) '((0 . "TEXT") )))
(cdr (assoc 1 (entget (ssname txtsel 0))))
","
); end if
); end setq
{code}
How can I get the Yline to work in the code?

I really do thank all of you for the help. I didn't want to ask for anyone to write my code for me but help with how to get some of the parts working. I didn't realise there were so many ways to look at it.

Thanks,
Chris
Message 14 of 16
curmudgeon
in reply to: framednlv

my apologies Kent, for not scrolling in the scroll box and reading the length of your string of code.

glad the fence selection is working for you.
there are two parts to the crossing, window, fence and crossing polygon selection sets.
the first is a points list - the second is a filter list. the filter list is where you put '((0 . "TEXT"))

you could
(setq pt_lst '( (43.378 522.674) ( 57.551 522.674) ) )
(setq txtsel (ssget "_f" pt_lst '((0 . "TEXT") )))

or

(setq pt_lst (list (list 43.378 (setq y 522.674)) (cons 57.551 y)))
(setq txtsel (ssget "_f" pt_lst '((0 . "TEXT") )))

or

(setq x1 (getpoint "\nPick X1 :")
x2 (getpoint x1 "\nPick X2 :")
y 522.674
my_list (list (cons x1 y) (cons x2 y))
txtsel (ssget "_f" pt_lst '((0 . "TEXT") )))
)

any of theses tickle your fancy?
Message 15 of 16
southie
in reply to: framednlv

working with layout tabs that could number in the hundreds and do not want program have to go to each tab to select text located at an x coord of 1.2. Would below be safe/good_programming_practice? Have used (foreach n (layoutlist) (setvar "ctab" n) (ssget "c".. in the past but its slow. Or is there a a better way?
Thanks

(setq index 0)
(setq ss (ssget "x" (list (cons 0 "text"))))
(repeat (sslength ss)
(setq ent (entget (ssname ss index))
ent1 (nth 0 (cdr (assoc 10 ent)))

(if (= ent1 1.2) (progn
do stuff.....

));if progn
(setq index (+ index 1))
);repeat
Message 16 of 16
framednlv
in reply to: framednlv

Thanks Everyone,

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost