Specify location of points relative to a reference line

Specify location of points relative to a reference line

Anonymous
Not applicable
1,675 Views
10 Replies
Message 1 of 11

Specify location of points relative to a reference line

Anonymous
Not applicable

Hi,

 

I have a line (3d) with defined chainage (km relative to a reference location). There are a list of fixed objects around the line, wherein the X-Y-Z coordinates of the objects are given. The line and the objects have the same origin and same coordinate system. I need to extract the location of the objects relative to the line, that is, the relative chainage and the distance to the line. Anyone knows how to extract the list of relative locations for those objects?

 

Thanks in advance!

 

ps. Attached is an example of a line with some objects around it. The objects are plot out based on their coordinates. Now I need to find the km-info of these points relative to the line and the distance to the line (NB. the line can containe lots of curves, just imaging a country road).

0 Likes
Accepted solutions (1)
1,676 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant
No attachment.
0 Likes
Message 3 of 11

Anonymous
Not applicable

Oh, now it's attached.

0 Likes
Message 4 of 11

dlanorh
Advisor
Advisor

You haven't attached a sample drawing (always a good thing) but try this

 

Select the line. Then select an "object". It will show an alert box containing the distance along the alignment and the distance from the alignment. Both are based on the mid-point of the "objects" bounding box.

The loop will repeat until a null selection (press enter or right click the mouse) is made.

 

(defun rh:gbbc (obj / ll ur lst c_pt)
  (if (and obj (= (type obj) 'ENAME))  (setq obj (vlax-ename->vla-object obj)))
  (cond (obj
          (vlax-invoke-method obj 'getboundingbox 'll 'ur)
          (setq lst (mapcar 'vlax-safearray->list (list ll ur))
                c_pt (mapcar '(lambda (x y) (/ (+ x y) 2.0)) (car lst) (cadr lst))
          );end_setq
        )
  );end_cond
  c_pt
);end_defun

(vl-load-com)

(defun c:doff (/ l_ent sel m_pt c_pt)
  (setq l_ent (car (entsel "\nSelect Reference Line : ")))
  
  (while (setq sel (entsel "\nSelect Object : "))
    (setq m_pt (rh:gbbc (vlax-ename->vla-object (car sel)))
          c_pt (vlax-curve-getclosestpointto l_ent m_pt)
    );end_setq
    (alert (strcat "Distance along Alignment : " (rtos (vlax-curve-getdistatpoint l_ent c_pt) 2 3)
                   "\n\n Distance from alignment : " (rtos (distance m_pt c_pt) 2 3)
           );end_strcat
    );end_alert
  );end_while

  (princ)
);end_defun

I am not one of the robots you're looking for

Message 5 of 11

Anonymous
Not applicable

Hi dlanorh!

 

Thanks a lot! It is nearly the one I need. Could be great to extend it for 'window select' to select all the objects at once. Then get an output as a list of objects with their station and offset to the reference line. I can have a try also.

 

Best regards

0 Likes
Message 6 of 11

dlanorh
Advisor
Advisor

Sorry, I've been out all day today, and will be again tomorrow. You don't say what the objects are, blocks? circles?; or how to identify them in any list. As I mentioned a sample drawing or dxf would have helped. Changing the code to work the way you want is easy if the above are known.

I am not one of the robots you're looking for

0 Likes
Message 7 of 11

Anonymous
Not applicable
Hi!

I don't have my pc with me...
The objects are points with given geo-coordinates:)
0 Likes
Message 8 of 11

dlanorh
Advisor
Advisor

When you get to your PC copy and paste this to the command line and press enter. Select one of the points when prompted. Then paste the answer into your reply. I have a feeling you're using civil and the points may have a different (assoc 0) to normal AutoCAD points, and as I don't use this vertical I have no idea what the entity type would be.

 

(cdr (assoc 0 (entget (car (entsel "\nSelect Point : ")))))

I am not one of the robots you're looking for

0 Likes
Message 9 of 11

Anonymous
Not applicable
No, I use normal autocad. Civil 3D has the tool "Add station and offset to
points" already.
It doesn't matter if it is geo-coordinate or any other coordinates, as long
as the points and the reference alignment have the same coordinate system
and origin. To test you can also draw a polyline and several points around
it:).
0 Likes
Message 10 of 11

dlanorh
Advisor
Advisor
Accepted solution

Try this. It writes out to a csv file X, Y and Z of point, chainage and offset. The csv is sorted by distance from origin.

 

(defun rh:gbbc (obj / ll ur lst c_pt)
  (if (and obj (= (type obj) 'ENAME))  (setq obj (vlax-ename->vla-object obj)))
  (cond (obj
          (vlax-invoke-method obj 'getboundingbox 'll 'ur)
          (setq lst (mapcar 'vlax-safearray->list (list ll ur))
                c_pt (mapcar '(lambda (x y) (/ (+ x y) 2.0)) (car lst) (cadr lst))
          );end_setq
        )
  );end_cond
  c_pt
);end_defun

(defun rh:get_file ( title fname ext flg )
  (if (not ext) (setq ftype "*" ext ".*") (setq ftype (vl-string-left-trim "." ext)))
  (cond ( (not flg) (setq fname (getfiled title (strcat (getvar 'dwgprefix) fname ext) ftype 1)))
        (flg (setq fname (getfiled title (strcat (getvar 'dwgprefix) fname ext) ftype 12)))
  );end_cond
);end_defun

(vl-load-com)

(defun c:doff (/ l_ent ss fname fp cnt ent m_pt c_pt p_lst)
  (setq l_ent (car (entsel "\nSelect Reference Line : ")))
  (prompt "\nSelect Objects : ")
  (setq ss (ssget '((0 . "POINT"))))
  (cond (ss
          (setq fname (rh:get_file "Enter CSV File Name for Output" (vl-filename-base (getvar 'dwgname)) ".csv" nil))
          (setq fp (open fname "w"))
          (write-line "Pt X,Pt Y,Pt Z,Chainage,Offset" fp)
          (repeat (setq cnt (sslength ss))
            (setq ent (ssname ss (setq cnt (1- cnt)))
                  m_pt (rh:gbbc (vlax-ename->vla-object ent))
                  c_pt (vlax-curve-getclosestpointto l_ent m_pt)
                  p_lst (cons (list (vlax-curve-getdistatpoint l_ent c_pt) (distance m_pt c_pt) m_pt) p_lst)
            );end_setq
          );end_repeat
          (setq p_lst (vl-sort p_lst '(lambda (x y) (< (car x) (car y)))))
          (foreach p p_lst
            (write-line (strcat (rtos (car (caddr p)) 2 3) "," (rtos (cadr (caddr p)) 2 3) "," (rtos (caddr (caddr p)) 2 3) "," 
                                (rtos (car p) 2 3) "," 
                                (rtos (cadr p) 2 3)
                        );end_strcat
                        fp
            );end_write-line
          );end_foreach
        )
        (t (princ "\nNOTHING Selected!"))
  );end_cond
  (close fp)
  (princ)
);end_defun

I am not one of the robots you're looking for

Message 11 of 11

Anonymous
Not applicable

Brilliant! Thanks a lot!

0 Likes