Results 1 to 6 of 6

Thread: Compare line endpoints to points and adjust lines

  1. #1
    I could stop if I wanted to
    Join Date
    2003-11
    Posts
    450
    Login to Give a bone
    0

    Default Compare line endpoints to points and adjust lines

    I have a drawing that has lines that represent sewer pipes and points that represent manholes. My problem is the line endpoints do not exactly match the points. I need a program that will snap the lines to the points they are closest to.

    My thoughts were to make a list of all the line endpoints and a list of all the manhole points then compare the two then if an endpoint is within a specific distance adjust the line endpoint so that it equals the manhole point.

    Does anybody know of an easier way to accomplish this?

    I will be converting the lines and points to a GIS database and it is best if lines and manholes match up exactly.
    Attached Files Attached Files

  2. #2
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: Compare line endpoints to points and adjust lines

    This is a brute-force method. It'll move the lines' start- and endpoints to the closest point selected:
    Code:
    ;;; Command to match line ends to closest point
    (defun c:Lines2Points (/ ss n en ed lines points)
      (prompt "\nSelect the lines & points to match: ")
      (setq ss (ssget '((0 . "LINE,POINT"))) ;Get a selection set from user
            n  0.0 ;Initialize counter to zero
      ) ;_ end of setq
      ;; Step through entire selection set
      (while (< n (sslength ss))
        (setq en (ssname ss n) ;Get entity's ename
              ed (entget en) ;And its DXF data
        ) ;_ end of setq
        (cond
          ((= "LINE" (cdr (assoc 0 ed))) ;If it's a line
           (setq lines (cons ed lines)) ;Add it to the lines list
          )
          ((= "POINT" (cdr (assoc 0 ed))) ;If it's a point
           (setq points (cons (cdr (assoc 10 ed)) points)) ;Add the point's XYZ to the points list
          )
        ) ;_ end of cond
        (setq n (+ n 1.0)) ;Increment counter
      ) ;_ end of while
    
      ;; Step through the lines list
      (foreach ed lines
        (setq n (FindClosest (cdr (assoc 10 ed)) points) ;Get closest point to start
              en (FindClosest (cdr (assoc 11 ed)) points) ;Get closest point to end
              )
        (setq ed (subst (cons 10 n) (assoc 10 ed) ed) ;New start point
              ed (subst (cons 11 en) (assoc 11 ed) ed) ;New end point
              )
        (entmod ed) ;Change the line
      ) ;_ end of foreach
    
      (princ)
    ) ;_ end of defun
    
    ;;; Helper function to find the closest point
    (defun FindClosest (pt lst / pt0 pt1 dist)
      (setq pt0  (car lst) ;Get the 1st point in list
            dist (distance pt pt0) ;Get the 1st distance
      ) ;_ end of setq
      (foreach pt1 lst ;Step through points list
        (if (< (distance pt pt1) dist) ;If distance is less
          (setq dist (distance pt pt1) ;Set new minimal distance
                pt0  pt1 ;Set new closest point
          ) ;_ end of setq
        ) ;_ end of if
      ) ;_ end of foreach
      pt0 ;Return the calculated closest point
    ) ;_ end of defun

  3. #3
    I could stop if I wanted to
    Join Date
    2003-11
    Posts
    450
    Login to Give a bone
    0

    Default Re: Compare line endpoints to points and adjust lines

    Thanks Irneb. I started to code something but your way is much better. Also, I would like to add a tolerance (ex. if the distance is over 10 feet then don't move line endpoint).

  4. #4
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: Compare line endpoints to points and adjust lines

    OK here's the 2nd try, changes marked in red:
    Code:
    (setq L2P:Tol 10.0) ;Global var to save the tolerance
    
    ;;; Command to match line ends to closest point
    (defun c:Lines2Points (/ ss tol n en ed lines points)
      (command "_UNDO""_BEgin")
      (prompt "\nSelect the lines & points to match: ")
      (setq ss (ssget '((0 . "LINE,POINT"))) ;Get a selection set from user
            n  0.0 ;Initialize counter to zero
      ) ;_ end of setq
    
      ;; Step through entire selection set
      (while (and ss (< n (sslength ss)))
        (setq en (ssname ss n) ;Get entity's ename
              ed (entget en) ;And its DXF data
        ) ;_ end of setq
        (cond
          ((= "LINE" (cdr (assoc 0 ed))) ;If it's a line
           (setq lines (cons ed lines)) ;Add it to the lines list
          )
          ((= "POINT" (cdr (assoc 0 ed))) ;If it's a point
           (setq points (cons (cdr (assoc 10 ed)) points)) ;Add the point's XYZ to the points list
          )
        ) ;_ end of cond
        (setq n (+ n 1.0)) ;Increment counter
      ) ;_ end of while
    
      (prompt (strcat "\nMatching " (itoa (length lines)) " lines to " (itoa (length points)) " points."))
    
      (if (setq tol (getdist (strcat "\nWhat's the maximum tolerance distance <" (rtos L2P:Tol) ">: "))) ;Ask user for tolerance
        (setq L2P:Tol tol) ;User specified new distance - set default for next time
        (setq tol L2P:Tol) ;User pressed Enter - get default from last time
      ) ;_ end of if
    
      (prompt "\nContinue to modify lines ... ")
    
      ;; Step through the lines list
      (foreach ed lines
        ;; Removed and condition and split start- and endpoints into 2 sepearate if statements
    
        (if (setq n (FindClosest (cdr (assoc 10 ed)) points tol)) ;Get closest point to start
          (setq ed (subst (cons 10 n) (assoc 10 ed) ed)) ;New start point
        ) ;_ end of if
    
        (if (setq en (FindClosest (cdr (assoc 11 ed)) points tol)) ;Get closest point to end
          (setq ed (subst (cons 11 en) (assoc 11 ed) ed)) ;New end point
        ) ;_ end of if
    
        (entmod ed) ;Change the line
      ) ;_ end of foreach
      (prompt "done.")
    
      (command "_UNDO" "_End")
      (princ)
    ) ;_ end of defun
    
    ;;; Helper function to find the closest point
    (defun FindClosest (pt lst dist / pt0 pt1 dt)
      (setq pt0  nil) ;Initializa the found point to nil
      ;; Removed calculate 1st point, return nil if not found
      (foreach pt1 lst ;Step through points list
        (if (< (setq dt (distance pt pt1)) dist) ;If distance is less
          (setq dist dt ;Set new minimal distance
                pt0 pt1 ;Set new closest point
          ) ;_ end of setq
        ) ;_ end of if
      ) ;_ end of foreach
      pt0 ;Return the calculated closest point
    ) ;_ end of defun
    Asks user for tolerance after selection. Defaults to 10.0, thereafter the tolerance defaults to previous. Also added some prompts to show totals & progress. As well as wraped the entire command in an UNDO group, so it can be undone in one step.
    Last edited by irneb; 2009-06-04 at 05:05 AM. Reason: Added colours to code

  5. #5
    I could stop if I wanted to
    Join Date
    2003-11
    Posts
    450
    Login to Give a bone
    0

    Default Re: Compare line endpoints to points and adjust lines

    Works great, thanks.

  6. #6
    Member
    Join Date
    2013-03
    Posts
    2
    Login to Give a bone
    0

    Default Re: Compare line endpoints to points and adjust lines

    Quote Originally Posted by irneb View Post
    OK here's the 2nd try, changes marked in red:
    Code:
    (setq L2P:Tol 10.0) ;Global var to save the tolerance
    
    ;;; Command to match line ends to closest point
    (defun c:Lines2Points (/ ss tol n en ed lines points)
      (command "_UNDO""_BEgin")
      (prompt "\nSelect the lines & points to match: ")
      (setq ss (ssget '((0 . "LINE,POINT"))) ;Get a selection set from user
            n  0.0 ;Initialize counter to zero
      ) ;_ end of setq
    
      ;; Step through entire selection set
      (while (and ss (< n (sslength ss)))
        (setq en (ssname ss n) ;Get entity's ename
              ed (entget en) ;And its DXF data
        ) ;_ end of setq
        (cond
          ((= "LINE" (cdr (assoc 0 ed))) ;If it's a line
           (setq lines (cons ed lines)) ;Add it to the lines list
          )
          ((= "POINT" (cdr (assoc 0 ed))) ;If it's a point
           (setq points (cons (cdr (assoc 10 ed)) points)) ;Add the point's XYZ to the points list
          )
        ) ;_ end of cond
        (setq n (+ n 1.0)) ;Increment counter
      ) ;_ end of while
    
      (prompt (strcat "\nMatching " (itoa (length lines)) " lines to " (itoa (length points)) " points."))
    
      (if (setq tol (getdist (strcat "\nWhat's the maximum tolerance distance <" (rtos L2P:Tol) ">: "))) ;Ask user for tolerance
        (setq L2P:Tol tol) ;User specified new distance - set default for next time
        (setq tol L2P:Tol) ;User pressed Enter - get default from last time
      ) ;_ end of if
    
      (prompt "\nContinue to modify lines ... ")
    
      ;; Step through the lines list
      (foreach ed lines
        ;; Removed and condition and split start- and endpoints into 2 sepearate if statements
    
        (if (setq n (FindClosest (cdr (assoc 10 ed)) points tol)) ;Get closest point to start
          (setq ed (subst (cons 10 n) (assoc 10 ed) ed)) ;New start point
        ) ;_ end of if
    
        (if (setq en (FindClosest (cdr (assoc 11 ed)) points tol)) ;Get closest point to end
          (setq ed (subst (cons 11 en) (assoc 11 ed) ed)) ;New end point
        ) ;_ end of if
    
        (entmod ed) ;Change the line
      ) ;_ end of foreach
      (prompt "done.")
    
      (command "_UNDO" "_End")
      (princ)
    ) ;_ end of defun
    
    ;;; Helper function to find the closest point
    (defun FindClosest (pt lst dist / pt0 pt1 dt)
      (setq pt0  nil) ;Initializa the found point to nil
      ;; Removed calculate 1st point, return nil if not found
      (foreach pt1 lst ;Step through points list
        (if (< (setq dt (distance pt pt1)) dist) ;If distance is less
          (setq dist dt ;Set new minimal distance
                pt0 pt1 ;Set new closest point
          ) ;_ end of setq
        ) ;_ end of if
      ) ;_ end of foreach
      pt0 ;Return the calculated closest point
    ) ;_ end of defun
    Asks user for tolerance after selection. Defaults to 10.0, thereafter the tolerance defaults to previous. Also added some prompts to show totals & progress. As well as wraped the entire command in an UNDO group, so it can be undone in one step.
    It is nice working I am looking for the same but to work with polylines.
    I know that it is more tricky to work with polylines, but may be you have already did it.

Similar Threads

  1. Replies: 19
    Last Post: 2012-11-13, 06:58 AM
  2. Replies: 1
    Last Post: 2011-11-18, 03:45 PM
  3. Cannot adjust elevation points on a floor
    By JONB.102117 in forum Revit Architecture - General
    Replies: 1
    Last Post: 2007-09-14, 06:52 PM
  4. Compare two sets of points
    By tany0070 in forum AutoLISP
    Replies: 6
    Last Post: 2007-03-22, 12:57 AM
  5. Replies: 4
    Last Post: 2006-02-28, 07:43 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •