+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 20
  1. #1
    Forum Newbie
    Computer Details
    Cristi_an_24's Computer Details
    Operating System:
    Win XP & Win 7
    Computer:
    Dell & HP
    Discipline
    Structural
    Cristi_an_24's Discipline Details
    Occupation
    Structural Designer
    Discipline
    Structural
    Details
    Shipbuilding
    Using
    AutoCAD 2009
    Join Date
    Jul 2012
    Location
    UK/Romania
    Posts
    8

    Default Lisp to draw a line between GPS points

    Registered forum members do not see this ad.

    Hi,

    I have tried to write a lisp to draw a line between 2 GPs points, the distance between them is calculated using havesine formula, but I get an error [; error: bad argument type: consp "56.06613,3.4514"], I believe that it doesn't recognise the coordinates for some reason, can someone help me with this.
    I have started to write this lisp for myself for fun, since I have a smartphone from where I can extract the GPS coordinates, and I wanted to see if I can mesure more accurate the size of my garden
    I have to admit that I am an begginer in lisp writing.


    Best regards,
    Cristian




    Code:
     
    ;draw real distances from GPS coordinates
    ;load points from csv files
    (Defun C:gpsd ( / dataL csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
    ;*******************load files***************
    (setq dataL '());define an empty list
    (setq csv_name "");define an empty name for file
    (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name 
    (setq ofil (open CSV_name "r")); define "ofile" as open the file
    (while (setq rd-pos (read-line ofil));read each line from file
    (setq dataL (cons rd-pos dataL));add each row to list
    );close while
    (close ofil);close file
    (setq dataL (reverse dataL));put list in right order
    (setq n (length dataL));get the number of points
    (setq Pi1 (nth 0 dataL));get initial GPS point
    (setq P1 '(0 0));set initial Real point to "0,0"
    (setq xi1 (car Pi1));get initial x from first point
    (setq yi1 (cadr Pi1));get initial y from first point
    (setq cntr 1)
    (while (<= cntr n)
    (setq P2n (nth cntr dataL));choose second GPS point by cntr
    (setq Pxn (car P2n));get x from second point
    (setq Pyn (cadr P2n));get y from second point
    (setq ang (angle Pi1 P2n));get angle between points
    (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
    ;calculate real distance
    (setq ED 6371000);earth diameter in metres
    (setq lat1 (* pi (/ xi1 180.0)));lat in rad
    (setq lat2 (* pi (/ Pxn 180.0)))
    (setq Dlat (* pi(/ (- Pxn xi1) 180.0)))
    (setq Dlong (* pi(/ (- Pyn yi1) 180.0))) 
    (setq a (+ (sin(/ 2 Dlat)^2) (* (* (cos lat1) (cos lat2)) (sin (/ 2 Dlong)^2))))
    (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
    (setq RD (* ED c));calculate real distance between GPs Points
    (setq RD (* RD 1000));convert distance from metres to mm
    (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
    (command ".line" P1 P2 "");draw a line as real distance between GPS points
    (setq ent (entlast));select last entoty created
    (setq entdata (entget ent));extract info from it
    (setq P1 (cdr (assoc 11 entdata)));reset Real P1 as (X2,Y2) from last line
    (setq Pi1 P2n);reset GPS Pi1 as next point
    (setq xi1 (car Pi1));recalculate x from new point
    (setq yi1 (cadr Pi1));recalculate y from new point
    ;reset counter
    (setq cntr (+ 1 cntr)) 
    );close while loop
    );close lisp
    ;***********csv file***********
    56.045809 -3.467674
    56.046754 -3.467043
    56.047555 -3.466557
    56.049877 -3.465697
    56.050516 -3.465509
    56.051126 -3.465203
    56.051486 -3.464872
    56.052003 -3.464229
    56.052626 -3.463154
    56.052887 -3.462645
    ;***********end csv***********
    Last edited by Cristi_an_24; 18th Jul 2012 at 04:53 pm.

  2. #2
    Super Moderator SLW210's Avatar
    Computer Details
    SLW210's Computer Details
    Operating System:
    Windows 7 PRO
    Computer:
    IBM Lenovo
    Motherboard:
    ACPI x86
    CPU:
    Pentium(R) Dual-Core CPU E5500 @ 2.80GHz
    RAM:
    4 GB RAM
    Graphics:
    Nvidia Quadro 600 1GB
    Primary Storage:
    300 GB
    Secondary Storage:
    650GB
    Monitor:
    ThinkVision 22"
    Discipline
    Multi-disciplinary
    SLW210's Discipline Details
    Occupation
    Design Draftsman
    Discipline
    Multi-disciplinary
    Details
    Mostly do drafting related to manufacturing. From doing site layouts with proposed updates, additions and renovations to be budgeted and submitted for bid, to updating and changing existing drawings to reflect maintenance and repair/revision work done on site.
    Using
    AutoCAD 2011
    Join Date
    May 2007
    Location
    South Florida, USA
    Posts
    9,125

    Default

    Please read the CODE POSTING GUIDELINES and edit your post to include CODE TAGS.
    “A narrow mind and a fat head invariably come on the same person” Zig Zigler



  3. #3
    Senior Member marko_ribar's Avatar
    Computer Details
    marko_ribar's Computer Details
    Operating System:
    Windows 7 Ultimate X64
    Computer:
    Intel quad core CPU 4x2.66GHz, 8GB RAM
    Motherboard:
    INTEL compatibile
    CPU:
    quad core 4x2.66GHz
    RAM:
    8GB
    Graphics:
    NVIDIA GeForce 6600 GT
    Primary Storage:
    250 GB
    Secondary Storage:
    500 GB
    Monitor:
    Samsung 17''
    Discipline
    Architectural
    marko_ribar's Discipline Details
    Occupation
    Architecture, project designer, project visualisation
    Discipline
    Architectural
    Details
    space design - modeling and animations
    Using
    AutoCAD 2012
    Join Date
    Feb 2010
    Location
    Belgrade, Serbia, Europe
    Posts
    331

    Default

    When you open CSV file in notepad - not excel, you'll notice that every cell in a row of CSV is separated by "," character, so you must find Xcoord and Ycoord separately and put them in list of points as these coordinates are later retrieved with car or cadr functions... Also ^ operand in lisp is unknown - check (expt) function for exponentiation...

    Not checked but these are my remarks... (highlighted) - you must test it and later improve...

    Code:
    ;draw real distances from GPS coordinates
    ;load points from csv files
    (Defun C:gpsd ( / Xcoord Ycoord dataL csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
    ;*******************load files***************
    (setq dataL '());define an empty list
    (setq csv_name "");define an empty name for file
    (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name 
    (setq ofil (open CSV_name "r")); define "ofile" as open the file
    (while (setq rd-pos (read-line ofil));read each line from file
    
    (setq Xcoord (substr rd-pos 1 (vl-string-position (ascii ",") rd-pos)))
    (setq Ycoord (substr rd-pos (+ (vl-string-position (ascii ",") rd-pos) 2) (- (strlen rd-pos) (vl-string-position (ascii ",") rd-pos) 1)))
    (setq dataL (cons (list (read Xcoord) (read Ycoord)) dataL));add each row to list
    
    );close while
    (close ofil);close file
    (setq dataL (reverse dataL));put list in right order
    (setq n (length dataL));get the number of points
    (setq Pi1 (nth 0 dataL));get initial GPS point
    (setq P1 '(0 0));set initial Real point to "0,0"
    (setq xi1 (car Pi1));get initial x from first point
    (setq yi1 (cadr Pi1));get initial y from first point
    (setq cntr 1)
    (while (<= cntr n)
    (setq P2n (nth cntr dataL));choose second GPS point by cntr
    (setq Pxn (car P2n));get x from second point
    (setq Pyn (cadr P2n));get y from second point
    (setq ang (angle Pi1 P2n));get angle between points
    (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
    ;calculate real distance
    (setq ED 6371000);earth diameter in metres
    (setq lat1 (* pi (/ xi1 180.0)));lat in rad
    (setq lat2 (* pi (/ Pxn 180.0)))
    (setq Dlat (* pi(/ (- Pxn xi1) 180.0)))
    (setq Dlong (* pi(/ (- Pyn yi1) 180.0))) 
    (setq a (+ (expt (sin (/ 2 Dlat)) 2) (* (* (cos lat1) (cos lat2)) (expt (sin (/ 2 Dlong)) 2))))
    (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
    (setq RD (* ED c));calculate real distance between GPs Points
    (setq RD (* RD 1000));convert distance from metres to mm
    (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
    (command ".line" P1 P2 "");draw a line as real distance between GPS points
    (setq ent (entlast));select last entoty created
    (setq entdata (entget ent));extract info from it
    (setq P1 (cdr (assoc 11 entdata)));reset Real P1 as (X2,Y2) from last line
    (setq Pi1 P2n);reset GPS Pi1 as next point
    (setq xi1 (car Pi1));recalculate x from new point
    (setq yi1 (cadr Pi1));recalculate y from new point
    ;reset counter
    (setq cntr (+ 1 cntr)) 
    );close while loop
    );close lisp
    M.R.

    Marko Ribar, d.i.a. (graduated engineer of architecture)
    M.R. on YouTube

  4. #4
    Forum Deity MSasu's Avatar
    Discipline
    Construction
    MSasu's Discipline Details
    Occupation
    engineer
    Discipline
    Construction
    Details
    AutoLISP programmer
    Using
    AutoCAD 2013
    Join Date
    Mar 2009
    Location
    Brasov, Romania
    Posts
    3,003

    Default

    I have marked in red the trouble maker code - the lines you got from data file are strings, while you attempt to treat them as list:
    Code:
    ...
    (setq Pi1 (nth 0 dataL));get initial GPS point
    (setq P1 '(0 0));set initial Real point to "0,0"
    (setq xi1 (car Pi1));get initial x from first point
    (setq yi1 (cadr Pi1));get initial y from first point
    ...
    Regards,
    Mircea

    AutoCAD's happy user equation: FILEDIA + PICKADD² + PICKFIRST = 3

  5. #5
    Forum Newbie
    Computer Details
    Cristi_an_24's Computer Details
    Operating System:
    Win XP & Win 7
    Computer:
    Dell & HP
    Discipline
    Structural
    Cristi_an_24's Discipline Details
    Occupation
    Structural Designer
    Discipline
    Structural
    Details
    Shipbuilding
    Using
    AutoCAD 2009
    Join Date
    Jul 2012
    Location
    UK/Romania
    Posts
    8

    Default

    Thanks, I will try tomorrow Marko's version, I was thinking that I am reading the each row from csv as a list of coordinates for each point, obviously I am wrong.

    Regards,
    Cristian

  6. #6
    Forum Newbie
    Computer Details
    Cristi_an_24's Computer Details
    Operating System:
    Win XP & Win 7
    Computer:
    Dell & HP
    Discipline
    Structural
    Cristi_an_24's Discipline Details
    Occupation
    Structural Designer
    Discipline
    Structural
    Details
    Shipbuilding
    Using
    AutoCAD 2009
    Join Date
    Jul 2012
    Location
    UK/Romania
    Posts
    8

    Default

    I need your help again, this time I believe the angle gets a negative value and my program stops, I tried to force my calculation to bring me positive values using "abs", but still nothing
    I have also change my code a bit, I am now calculating the distances relative to the first poing, get the real x&y, I store them into a list and at the end I want to draw a line to connect all the dots.

    Code:
     
    ;draw real distances from GPS coordinates
    ;load points from csv files
    (Defun C:gpx ( / Xcoord Ycoord dataL Rpt csv_name ofil rd-pos n Pi1 P1 cntr P2n ang ED lat1 lat2 Dlat Dlong a c RD ent entdata)
    ;*******************load files***************
    (setq dataL '());define an empty list
    (setq Rpt '());define an empty list for points
    (setq csv_name "");define an empty name for file
    (setq csv_name (getfiled "Select Point List .csv file" "" "csv" 2));get the file name 
    (setq ofil (open CSV_name "r")); define "ofile" as open the file
        (while (setq rd-pos (read-line ofil));read each line from file
            (setq Xcoord (substr rd-pos 1 (vl-string-position (ascii ",") rd-pos)))
            (setq Ycoord (substr rd-pos (+ (vl-string-position (ascii ",") rd-pos) 2) (- (strlen rd-pos) (vl-string-position (ascii ",") rd-pos) 1)))
            (setq dataL (cons (list (read Xcoord) (read Ycoord)) dataL));add each row to list
        );close while
    (close ofil);close file
    (setq dataL (reverse dataL));put list in right order
    (setq n (length dataL));get the number of points
    (setq Pi1 (nth 0 dataL));get initial GPS point
    (setq P1 '(0 0));set initial Real point to "0,0"
    (setq xi1 (car Pi1));get initial x from first point
    (setq yi1 (cadr Pi1));get initial y from first point
    (setq Rpt (cons P1 Rpt));add P1 on list as 0,0
    (setq cntr 1)
    (while (<= cntr n)
        (setq P2n (nth cntr dataL));choose second GPS point by cntr
        (setq Pxn (car P2n));get x from second point
        (setq Pyn (cadr P2n));get y from second point
        (setq ang (angle Pi1 P2n));get angle between points
        (setq ang (* 180.0 (/ ang pi)));convert angles from radians to degrees
    ;calculate real distance
       (setq ED 6371000);earth diameter in metres
       (setq lat1 (abs(* pi (/ xi1 180.0))));lat in rad
       (setq lat2 (abs(* pi (/ Pxn 180.0))))
       (setq Dlat (abs (* pi(/ (- Pxn xi1) 180.0))));abs added 
       (setq Dlong (abs (* pi(/ (- Pyn yi1) 180.0))));abs added 
       (setq a (+ (expt (sin (/ 2 Dlat)) 2) (* (* (cos lat1) (cos lat2)) (expt (sin (/ 2 Dlong)) 2))))
       (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))));calculate earth angle
       (setq RD (* ED c));calculate real distance between GPs Points
       (setq RD (* RD 1000));convert distance from metres to mm
       (setq P2 (polar P1 ang RD));calculate Real P2 by distance and angle
       (setq Rpt (cons P2 Rpt));add next point to the list  
    ;reset counter
      (setq cntr (+ 1 cntr)) 
    );close while loop
    (setq Rpt (reverse RPT));put the list in the right order
     (command ".line" Rpt "");draw a line as real distance between GPS points
    );close lisp
    "; error: function undefined for argument: -0.0577494"
    for points:
    56.06613 3.4514
    56.06671 3.45163
    56.06694 3.44979
    56.0663 3.44959

    and
    ; error: bad argument type: 2D/3D point: nil
    for this list of points:
    56.045809 -3.467674
    56.046754 -3.467043
    56.047555 -3.466557
    56.049877 -3.465697



    what is wrong in my code?



    Thanks,
    Cristian

  7. #7
    Forum Deity MSasu's Avatar
    Discipline
    Construction
    MSasu's Discipline Details
    Occupation
    engineer
    Discipline
    Construction
    Details
    AutoLISP programmer
    Using
    AutoCAD 2013
    Join Date
    Mar 2009
    Location
    Brasov, Romania
    Posts
    3,003

    Default

    First, please pay attention to the number of items you try to walk on the list:
    Code:
    (while (<= cntr n)
    (while (< cntr n)
    Second, the line cannot be drawn by using the list of points as argument:
    Code:
    (command ".line" Rpt "")
    (command "_.LINE")
    (foreach point Rpt
     (command "_non" point)
    )
    (command "")
    Regards,
    Mircea

    AutoCAD's happy user equation: FILEDIA + PICKADD² + PICKFIRST = 3

  8. #8
    Forum Newbie
    Computer Details
    Cristi_an_24's Computer Details
    Operating System:
    Win XP & Win 7
    Computer:
    Dell & HP
    Discipline
    Structural
    Cristi_an_24's Discipline Details
    Occupation
    Structural Designer
    Discipline
    Structural
    Details
    Shipbuilding
    Using
    AutoCAD 2009
    Join Date
    Jul 2012
    Location
    UK/Romania
    Posts
    8

    Default

    Thanks Mircea,
    I have changed my code with your recomandations but i still get this error: "; error: function undefined for argument: -0.00160928", I have attached my list of points as well as text file.

    Thanks again,
    Cristian
    Attached Files

  9. #9
    Forum Deity MSasu's Avatar
    Discipline
    Construction
    MSasu's Discipline Details
    Occupation
    engineer
    Discipline
    Construction
    Details
    AutoLISP programmer
    Using
    AutoCAD 2013
    Join Date
    Mar 2009
    Location
    Brasov, Romania
    Posts
    3,003

    Default

    There is an inconsistency between the code and example file – the separator used in the file is <Tab> instead of comma considered in code; so you should use;
    Code:
    (ascii "\t")
    instead of:
    Code:
    (ascii "\,")
    Regards,
    Mircea

    AutoCAD's happy user equation: FILEDIA + PICKADD² + PICKFIRST = 3

  10. #10
    Forum Deity MSasu's Avatar
    Discipline
    Construction
    MSasu's Discipline Details
    Occupation
    engineer
    Discipline
    Construction
    Details
    AutoLISP programmer
    Using
    AutoCAD 2013
    Join Date
    Mar 2009
    Location
    Brasov, Romania
    Posts
    3,003

    Default

    Registered forum members do not see this ad.

    The problem is from the fact that square root have meaning only for positive numbers; in at least one case the argument become negative.
    Code:
    (setq c (* 2 (atan (sqrt a) (sqrt (- 1 a)))))
    You should validate again your formulas - I cannot check them since don't know from where come from.

    The (at least first) trouble-maker pair of data is:
    56.0534 -3.46219
    Regards,
    Mircea

    AutoCAD's happy user equation: FILEDIA + PICKADD² + PICKFIRST = 3

Similar Threads

  1. Replies: 21
    Last Post: 13th May 2013, 07:15 pm
  2. Draw a line from points divided to a point that i pick.
    By j_spawn_h in forum AutoLISP, Visual LISP & DCL
    Replies: 8
    Last Post: 27th Nov 2011, 07:07 pm
  3. draw symbol at line start points
    By rob8lyn in forum AutoCAD General
    Replies: 6
    Last Post: 29th Jun 2011, 04:38 pm
  4. draw line on line (auto select previous pick points)
    By deano33 in forum AutoCAD 2D Drafting, Object Properties & Interface
    Replies: 4
    Last Post: 10th Dec 2009, 09:59 pm
  5. Draw a dotted line btw two points
    By Maradona_10 in forum AutoLISP, Visual LISP & DCL
    Replies: 2
    Last Post: 26th May 2008, 05:35 pm

Bookmarks

Posting Permissions

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