Author Topic: Can I pull data from a map grid of lines to feed a number to an Attribute  (Read 6569 times)

0 Members and 1 Guest are viewing this topic.

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
I have map grid that I over lay floor plans of a hospital that the hospital used to locate stuff and equipment.  This fixed equipment and room numbers within the hospital get a tag with number that represent it location in retrospect to the map grid. We have to go through and drop symbols of this equipment into the floor plans and then enter the location into an attribute.  Need I say we have a boat load of equipment to tag and doing through out the hospital manually will take a good bit of time and lead to error from users inputting the location manually.  And I was hoping to reduce that.

This is Map grid that has two components.  First it has a simple map grid with alpha characters on the side and numbers across the top.  Within each grid (or square that the grid line makes up) there are 600 smaller squares.  And these 600 smaller squares are repeated in for each grid.  ( see attached file)

My question, can lisp pull the numbers from both the Map Grid and smaller squares by making one simple pick with in the smaller square.  The format of the return will be "floor-mapgrid-smallersquare"  For example  01-E06-458 would be location number.

Need I say, we have a boat load of equipment to tag and doing through out the hospital will take a good bit of time and lead to error from users if they are inputting the location manually.  And I was hoping to reduce that.  I have to generate code to insert the block and input other information that is part of this task too but I was hoping to some how bring this part in.  

**edit** Updated Drawing File  and posted sample block
« Last Edit: December 14, 2009, 02:06:59 PM by Krushert »
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #1 on: December 11, 2009, 10:34:44 PM »
Hmm, tough task... mainly because there is no inherent method in LISP/Visual to determine whether a point lies inside a boundary...

My initial thought on how to approach this would be something like:

  • Prompt for Point
  • Create temporary lines (of length 1 perhaps) at the selected point that are orthogonal to each other (going in x & y directions)
  • Use IntersectWith method to determine the points at which the temporary lines meet the grid lines
  • Determine the Parameter of the Grid-Line at the Point at the Intersection (vlax-curve-getParamatPoint), and use this to determine which Grid Square you are in

But, this would be by no means robust...  just one way to approach it.

Hope this helps,

Lee

cadabyss

  • Guest
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #2 on: December 12, 2009, 12:21:18 AM »
I haven't tested this but just off the top of my head: If you have a block inserted onto a grid, seems like the coordinate of that block could be used to map which cell in the grid the block is inserted in.  Take the X coordinate from the block insertion point and subtract that value from the X coordinate of vertical line 'A'.  Call the result DeltaX. Take the Y coordinate from the block insertion point and subtract that value from the Y coordinate of horizontal line '01'.  Call that result DeltaY. Then it's just a matter of testing the DeltaX and DeltaY values against a numerical range to determine grid location.

For example, to find the main column letter:

(setq ColumnWidth 1838.0167)
(cond
  ( (<= 0 DeltaX ColumnWidth) "A")
  ( (<= ColumWidth DeltaX (* 2 ColumnWidth)) "B")
  ( (<= (* 2 ColumnWidth) DeltaX (* 3 ColumnWidth)) "C")
  ...
)
 
Repeat that idea for DeltaY to find the main row number

Then once you get the main column and row numbers, repeat the entire process getting a new DeltaX and a new DeltaY relative from the intersection of the main column and row numbers.  Make sense?





My question, can lisp pull the numbers from both the Map Grid and smaller squares by making one simple pick with in the smaller square.  The format of the return will be "floor-mapgrid-smallersquare"  For example  01-E06-458 would be location number.


Lee Mac

  • Seagull
  • Posts: 12929
  • London, England
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #3 on: December 12, 2009, 06:29:12 AM »
Take the X coordinate from the block insertion point and subtract that value from the X coordinate of vertical line 'A'.  Call the result DeltaX. Take the Y coordinate from the block insertion point and subtract that value from the Y coordinate of horizontal line '01'.  Call that result DeltaY.

A much better solution.. not quite sure what I was thinking...  :oops:

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #4 on: December 12, 2009, 10:28:23 AM »
Code: [Select]
;;  CAB 12.12.2009
;; Proof of concept
;;  Returns the cell index Base 0,0 from lower left
;;  Index can be changed to 1,1
;;  Index orientation can be changed to Upper Left for Base
(defun c:test(/ bp Stepx Stepy pt ptx pty x y xc yc xs ys)
  (setq bp (getpoint "\nPick Lower Left Base point:"))
  (setq Stepx (getdist "\nEnter or pick X Grid dist:"))
  (setq Stepy (getdist "\nEnter or pick Y Grid dist:"))

  (setq pt (getpoint "\nPick point to locate:"))

  (setq ptx (car pt)
        pty (cadr pt)
        x   (- ptx (car bp))
        y   (- pty (cadr bp))
        xc  (fix (/ x Stepx)) ; Cell Number
        yc  (fix (/ y Stepy))
        xs  (fix (* (rem x 1) 1000)) ; Subcell index grid based on 1000x1000
        ys  (fix (* (rem y 1) 1000)) ; all based on 0,0 lower left
        )
  ;;  The whole number will be the Cell reference
  (princ "\nX grid cell #")(princ xc)
  (princ "\nY grid cell #")(princ Yc)
  ;;  the fraction is the sub Cell reference
  (princ "\nX sub cell #")(princ xs)
  (princ "\nY sub cell #")(princ Ys)

  (princ "\n-----------------------------")
  (princ "\nX grid cell index ")(princ (chr (+ xc 65)))
  (princ "\nY grid cell index ")(princ (- 12 Yc))
 
  (princ)
)

<revised code>
« Last Edit: December 12, 2009, 01:10:31 PM by CAB »
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #5 on: December 12, 2009, 09:44:17 PM »
Here is more code to get the column, row and sub cell in the grid.
Note that the result depends on the accuracy of the grid.
The grid in the DWG posted is NOT accurate! :?

Code: [Select]
;;  CAB 12.12.2009
;; Proof of concept
;;  Base 0,0 from lower left
;;  Index can be changed to 1,1
;;  Index orientation can be changed to Upper Left for Base
(defun c:test(/ bp Stepx Stepy pt ptx pty x y xc yc xs ys tmp)

 
  ;(setq bp '(0.0 2.27374e-013 0.0))
  (setq bp (getpoint "\nPick Lower Left Base point:"))
  ;(setq Stepx 1800.)
  ;(setq Stepy 1200.)
  (setq Stepx (getdist "\nEnter or pick X Grid dist:"))
  (setq Stepy (getdist "\nEnter or pick Y Grid dist:"))

  (or SubX (setq SubX 30))
  (or SubY (setq SubY 20))

 
  (initget 6)
  (setq tmp (getint
              (strcat "\nEnter X-axis number of boxes inside grid. <"(itoa SubX)">")))
  (and tmp (setq SubX tmp))
 
  (initget 6)
  (setq tmp (getint
              (strcat "\nEnter Y-axis number of boxes inside grid. <"(itoa SubY)">")))
  (and tmp (setq SubY tmp))
 

  (setq pt (getpoint "\nPick a point to locate Insert Point:"))
(command "point" "non" pt)
  (setq ptx (car pt)
        pty (cadr pt)
        x   (- ptx (car bp)) ; relative offset x
        y   (- pty (cadr bp))
        xc  (fix (/ x Stepx)) ; Cell Number
        yc  (fix (/ y Stepy))
        )
  ;;  The whole number will be the Cell reference
  (princ "\nX grid cell #")(princ xc)
  (princ "\nY grid cell #")(princ Yc)

  (princ "\n-----------------------------")
  (princ "\nX grid cell index ")(princ (chr (+ xc 65)))
  (princ "\nY grid cell index ")(princ (- 12 Yc))

  ;;  Set up the sub boxes
  (setq subXs (/ Stepx Subx)
        subYs (/ Stepy Suby)
        col  (fix (+ 0.99999 (/ (* (rem (/ X StepX) 1) Stepx) subXs)))
        row  (fix (+ 0.99999 (/ (* (rem (/ y Stepy) 1) Stepy) subYs)))
        )
 
  ;;  the fraction is the sub Cell reference
  (princ "\nX sub cell col #")(princ col)
  (princ "\nY sub cell row #")(princ row)
  (princ "\nCell #")(princ (- (* Subx Suby) (- (* Subx row) col))  )

  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ronjonp

  • Needs a day job
  • Posts: 7533
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #6 on: December 13, 2009, 12:15:07 AM »
So I woke up a 3am because the dogs were restless and started coding....my usual over thought half baked process came up with this:

Code: [Select]
(defun c:xx (/    ltr   num  out pp pt     sub_lst
    tmp    tmp2   x2_+  x_+ x_id x_lst  y2_-   y_-
    y_id   y_lst  id
   )
  (if (setq pt (getpoint "\nPick upper left hand corner of grid: "))
    (progn
      (setq x_+ 1800)
      (setq y_- 1200)
      (setq x2_+ 60)
      (setq y2_- 60)
      (setq tmp (- (car pt) x_+))
      (setq tmp2 (+ (cadr pt) y_-))
      (repeat 26
(setq x_lst (cons (list (setq tmp (+ tmp x_+)) (+ tmp x_+)) x_lst)
     y_lst (cons (list (setq tmp2 (- tmp2 y_-)) (- tmp2 y_-)) y_lst)
)
      )
      (setq x_lst (reverse x_lst)
   y_lst (reverse y_lst)
      )
      (while (setq pp (getpoint "\nPick random point: "))
(setq x_id (car (vl-remove-if-not
 '(lambda (x)
    (and (> (car pp) (car x)) (< (car pp) (cadr x)))
  )
 x_lst
)
  )
     y_id (car (vl-remove-if-not
 '(lambda (x)
    (and (< (cadr pp) (car x)) (> (cadr pp) (cadr x)))
  )
 y_lst
)
  )
)
(if (and x_id y_id)
 (progn (setq ltr     (chr (+ 65 (vl-position x_id x_lst)))
      num     (rtos (1+ (vl-position y_id y_lst)) 2 0)
      pt      (list (+ (car x_id) (* 0.5 x2_+))
    (- (car y_id) (* 0.5 y2_-))
    0.0
      )
      tmp     (- (car pt) x2_+)
      tmp2    y2_-
      sub_lst nil
      out     nil
)
(repeat (fix (/ x_+ x2_+))
  (setq sub_lst
 (cons (list (setq tmp (+ tmp x2_+)) (cadr pt) 0.0)
sub_lst
 )
  )
)
(setq out (list (reverse sub_lst)))
(repeat (1- (fix (/ y_- y2_-)))
  (setq out
 (cons
   (reverse
     (mapcar
(function (lambda (x)
   (list (car x) (- (cadr x) tmp2) 0.0)
 )
)
sub_lst
     )
   )
   out
 )
  )
  (setq tmp2 (+ tmp2 y2_-))
)
(setq out (apply 'append (reverse out)))
(setq id
(car (vl-sort
      (mapcar
(function (lambda (x) (cons x (distance pp x))))
out
      )
      (function (lambda (d1 d2) (< (cdr d1) (cdr d2))))
    )
)
)
(alert (strcat ltr
(if (= (strlen num) 1)
 (strcat "0" num)
 num
)
"-"
(rtos (1+ (vl-position (car id) out)) 2 0)
)
)
 )
 (alert "OH NOES!!! Out of grid range homeslice...")
)
      )
    )
  )
  (princ)
)

Then my buddy Tim (atook) came over and actually did some logical math. I tried to translate his VB code and came up with this:

Code: [Select]
(defun c:xx
       (/ h letter x_row y_row num pp pt1 pt2 y_subn y_subd subn x_subn x_subd w)
  (if (and (setq pt1 (getpoint "\nPick upper left corner of grid: "))
  (setq pt2 (getcorner pt1 "\nPick bottom right corner of cell: "))
  (setq x_subn (getint "\nEnter # of sub-cells wide: "))
  (setq y_subn (getint "\nEnter # of sub-cells high: "))
  (setq pp (getpoint "\nPick a random point: "))
      )
    (progn (setq w (- (car pt1) (car pt2)))
  (setq h (- (cadr pt1) (cadr pt2)))
  (setq x_subd (/ w x_subn))
  (setq y_subd (/ h y_subn))
  (setq x_row (fix (/ (- (car pt1) (car pp)) w)))
  (setq y_row (fix (/ (- (cadr pt1) (cadr pp)) h)))
  (setq pt1 (list (- (car pt1) (* x_row w)) (- (cadr pt1) (* y_row h))))
  (setq letter (chr (+ 65 x_row)))
  (setq num (1+ y_row))
  (setq subn (+ (fix (/ (- (car pt1) (car pp)) x_subd))
(* (fix (/ (- (cadr pt1) (cadr pp)) y_subd)) x_subn)
     )
  )
  (alert (strcat letter (rtos num 2 0) "-" (itoa (1+ subn))))
    )
  )
  (princ)
)

It's cool to see how different minds solve problems   8-)

*Here's the code to update an attribute value (the tagname needs to be modified to suit)


Code: [Select]
(defun c:gridloc2att (/ h letter num pp pt1 pt2 ss subn sub_tl w x_row x_subd x_subn
     y_row y_subd y_subn)
  (if (and (setq pt1 (getpoint "\nPick upper left corner of grid: "))
  (setq pt2 (getcorner pt1 "\nPick bottom right corner of cell: "))
  (setq x_subn (getint "\nEnter # of sub-cells wide: "))
  (setq y_subn (getint "\nEnter # of sub-cells high: "))
  (setq ss (ssget ":L" '((0 . "insert") (66 . 1))))
  (setq w (- (car pt1) (car pt2)))
  (setq h (- (cadr pt1) (cadr pt2)))
  (setq x_subd (/ w x_subn))
  (setq y_subd (/ h y_subn))
      )
    (foreach b (mapcar 'vlax-ename->vla-object
      (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))
      )
      (if
(and (setq pp (vlax-get b 'insertionpoint))
    (setq x_row (fix (/ (- (car pt1) (car pp)) w)))
    (setq y_row (fix (/ (- (cadr pt1) (cadr pp)) h)))
    (setq sub_tl (list (- (car pt1) (* x_row w)) (- (cadr pt1) (* y_row h))))
    (setq letter (chr (+ 65 x_row)))
    (setq num (rtos (1+ y_row) 2 0))
    (setq subn
   (itoa (1+ (+ (fix (/ (- (car sub_tl) (car pp)) x_subd))
(* (fix (/ (- (cadr sub_tl) (cadr pp)) y_subd)) x_subn)
     )
 )
   )
    )
)
(foreach att (vlax-invoke b 'getattributes)
  ;;Change attribute tag name to name needed
  (if (eq "TEST" (vla-get-tagstring att))
    (vla-put-textstring
      att
      (strcat letter
      (if (= (strlen num) 1)
(strcat "0" num)
num
      )
      "-"
      (cond ((= (strlen subn) 1) (strcat "00" subn))
    ((= (strlen subn) 2) (strcat "0" subn))
    (subn)
      )
      )
    )
  )
)
      )
    )
  )
  (princ)
)
« Last Edit: December 13, 2009, 10:27:35 AM by ronjonp »

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #7 on: December 13, 2009, 10:26:22 AM »
Nice jon Ron.
All we need now is a sample DWG with the INSERTS to be detected and mapped.

Here is my code with all the Fat removed.  8-)
Code: [Select]
(defun c:test (/ bp Stepx Stepy SubX SubY pt ptx pty x y)
 (and
  (setq bp (getpoint "\nPick Lower Left Base point:"))
  (setq Stepx (getdist "\nEnter or pick X Grid dist:"))
  (setq Stepy (getdist "\nEnter or pick Y Grid dist:"))
  (setq SubX (getint "\nEnter X-axis number of boxes inside grid. "))
  (setq SubY (getint "\nEnter Y-axis number of boxes inside grid. "))
  (setq pt (getpoint "\nPick a point to locate Insert Point:"))
  (setq ptx (car pt)
        pty (cadr pt)
        x   (- ptx (car bp))  ; relative offset x
        y   (- pty (cadr bp))
  )
  (princ "\nX grid cell index ") (princ (chr (+ (fix (/ x Stepx)) 65)))
  (princ "\nY grid cell index ") (princ (- 12 (fix (/ y Stepy))))
  (setq col (fix (+ 0.99999 (/ (* (rem (/ X StepX) 1) Stepx) (/ Stepx Subx))))
        row (fix (+ 0.99999 (/ (* (rem (/ y Stepy) 1) Stepy) (/ Stepy Suby))))
  )
  (princ "\nCell #") (princ (- (* Subx Suby) (- (* Subx row) col)))
 )
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

ronjonp

  • Needs a day job
  • Posts: 7533
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #8 on: December 13, 2009, 10:29:51 AM »
Nice work CAB ... short and sweet  :kewl:

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #9 on: December 13, 2009, 11:31:24 AM »
I suppose picking the upper left is a better idea if that is going to be the origin of the grid.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #10 on: December 13, 2009, 04:16:26 PM »
 :-o :-o  Wow Guys Did you leave any fish for me?  I logged on to find look up a post in the Lagniappe section of TheSwamp and .... BRB
...
...
...
...
Okay I am back - Had to change a diaper  - Hey Ronjonp has Dogs - I got kids.  :lol:
... and found you guys going to town.   Any way I am home without the the required blocks.  Look for something from me tomorrow afternoon


Thanks again guys.  This makes me want to unplug and move the computer into the dining room for tonight.
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #11 on: December 14, 2009, 09:31:51 AM »
Here is more code to get the column, row and sub cell in the grid.
Note that the result depends on the accuracy of the grid.
The grid in the DWG posted is NOT accurate! :?

Cab
How so and where?  I did not generate this grid but being what it is and it size, it would not surprise me.
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #12 on: December 14, 2009, 09:54:03 AM »
The X axis distance is incorrect!  Should be 1800, no?

Code: [Select]
Command: '_dist Specify first point:  Specify second point:
Distance = 1838.01665,  Angle in XY Plane = 0.0000,  Angle from XY Plane =
0.0000
Delta X = 1838.01665,  Delta Y = 0.00000,   Delta Z = 0.00000

I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #13 on: December 14, 2009, 10:40:15 AM »
The X axis distance is incorrect!  Should be 1800, no?

Code: [Select]
Command: '_dist Specify first point:  Specify second point:
Distance = 1838.01665,  Angle in XY Plane = 0.0000,  Angle from XY Plane =
0.0000
Delta X = 1838.01665,  Delta Y = 0.00000,   Delta Z = 0.00000


Yes it should be 1800.  At least two bays (A & B) but the wrong bays to have a screw up in.  Thanks Cab.  I will be back.  Time to thump on a architect.
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans

Krushert

  • Seagull
  • Posts: 13679
  • FREE BEER Tomorrow!!
Re: Can I pull data from a map grid of lines to feed a number to an Attribute
« Reply #14 on: December 14, 2009, 02:06:11 PM »
OKay Corrections to the grid made and a sample block posted to OP.

Code: [Select]
  (if (and (setq pt1 (getpoint "\n[b]Pick upper left corner of grid: [/b]"))
   (setq pt2 (getcorner pt1 "\n[b]Pick bottom right corner of cell:[/b] "))
   (setq x_subn (getint "\n[b]Enter # of sub-cells wide:[/b] "))
   (setq y_subn (getint "\n[b]Enter # of sub-cells high:[/b] "))

OKay you guys lost me.  I am not understanding this prompts. 

Pick upper left corner of grid: Is this very top left A 01?

Pick bottom right corner of cell: Is the cell that inserted block resides in?

Enter # of sub-cells wide (& high):  Okay this is throwing me even more.

I thus the block in D07-433 and I end up with A01-643.  I only have 600 cells in a grid?
« Last Edit: December 14, 2009, 02:19:50 PM by Krushert »
I + XI = X is true ...  ... if you change your perspective.

I no longer CAD or Model, I just hang out here picking up the empties beer cans