Longitude, Longitude to X, Y format

Longitude, Longitude to X, Y format

nicolasR6NGC
Contributor Contributor
853 Views
10 Replies
Message 1 of 11

Longitude, Longitude to X, Y format

nicolasR6NGC
Contributor
Contributor
(defun GeoMarker ( / )
  (entmakex '((0 . "POSITIONMARKER") 
              (100 . "AcDbEntity") 
              (100 . "AcDbGeoPositionMarker") 
              (90 . 0) 
              (10 0.0 0.0 0.0) 
              (40 . 1.0) 
              (1 . "")))
)
    
(setq new_points '())  ;; Initialize new_points list
    
(foreach point points
  (setq nest '())  ;; Initialize nest list for each iteration
      
  ;; Create a GeoMarker at origin
  (setq origin_marker (GeoMarker))
      
  ;; Make GeoMarker a VLA object
  (setq om (vlax-ename->vla-object origin_marker))

  ;; Set the Longitude and Latitude properties on the entity (make sure they exist)
  (vlax-put-property om 'Longitude (car point))
  (vlax-put-property om 'Latitude (cadr point))

  ;; Get the X and Y position values from the entity (ensure getpropertyvalue works as expected)
  (setq pos-x (getpropertyvalue origin_marker "Position/X"))
  (setq pos-y (getpropertyvalue origin_marker "Position/Y"))
      
  ;; Ensure pos-x and pos-y are numbers before continuing
  (if (and (numberp pos-x) (numberp pos-y))
    (progn
      ;; Set the new point with Z value as 0
      (setq nest (list pos-x pos-y 0.0))
      ;; Append new point to new_points list (consider using cons for performance)
      (setq new_points (append new_points (list nest)))
    )
    (progn
      (princ "Error: Invalid coordinate values!")
    )
  )

  ;; Delete the created marker
  (entdel origin_marker)
)

TLDR: I'm trying to convert the longitude and latitude of a list of points into cartesian coordinates and the resulting list refuses to be sent anywhere outside the main code line.

 

I'm making a script that takes a path drawn on a KMZ file and retrieves all parcel lines within a 1000 foot area. To accomplish this I have LISP run a py executable that creates a square region around a drawn path and stores the lat and long of the polyline into a csv file. Afterwards I import the csv into LISP and parse out the lat and long into a nested list where each list represents a point with this format (long (x), lat (y)). EX: ((Long1, Lat1), (Long2, Lat2), etc). The problem that is semi solved, is that I need to convert this coordinate system to cartesian coordinates so that the line is drawn in the correct place. I accomplished this by making a geomarker and moving it to the location defined by the coordinates then recording the x and y position of the geomarker before deleting it. The x and y are correct but the problem I'm having is that I can't send the list anywhere without it breaking. Chatgpt said it maybe because the lisp is evaluating the list as a function instead of data. However, I can't figure out how to avoid this misinterpretation. The best solution I came up with is not making this process a definition with a return item but instead keeping it in the main code block. While this work around works in drawing a polyline I would like to use the cartesian coordinates to find what parcel line objects fall within the created region. Any ideas how to avoid this issue? Also I just found out I can't use ADE Query so any ideas on how to automate this as well?   

0 Likes
854 Views
10 Replies
Replies (10)
Message 2 of 11

CodeDing
Advisor
Advisor

@nicolasR6NGC ,

 

Are you using Civil 3D, Map 3D, or Vanilla AutoCAD?

0 Likes
Message 3 of 11

CodeDing
Advisor
Advisor

@nicolasR6NGC ,

 

If you are using Civil 3D or Map 3D, then you can use this version to get your X/Y coordinates:

 

;; String to List  -  Lee Mac
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
(defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
)

;; Retrieves Lat/Long coordinates from output.csv file
;; output.csv must be formatted, ignoring first row, like: [name],[type],[lat],[lon]
;; fPath - string, path to csv file
;; returns - list, of lat/long coordinates like: ((Lon Lat) (Lon Lat) ...)
(defun GetCoordData (fPath / f str strList return)
  (if (setq fPath (findfile fPath))
    (progn
      (setq f (open fPath "r"))
      (read-line f)
      (while (setq str (read-line f))
        (setq strList (cons str strList))
      );while
      (close f)
      (if strList
        (setq return
          (mapcar
            '(lambda (s / )
              (reverse (mapcar 'atof (cddr (LM:str->lst s ","))))
            );lambda
            (reverse strList)
          );mapcar
        );setq
      ;else
        (prompt "\nNo coordinates found in CSV file.")
      );if
    );progn
  ;else
    (prompt "\nCSV file not found.")
  );if
  return
);defun

;; Turns a list of (longs lats) into coordinates ..ONLY useable if dwg is Geo-Located.
;; LLs - list, of points as ((long lat) (long lat) ...) 
;; returns - list of points, as ((X Y) (X Y) ...) since longitudes represent "x" values & Latitudes represent "y" values
(defun LLs->PTs (LLs / )
  (ade_projsetsrc (getvar 'CGEOCS))
  (ade_projsetdest "LL84")
  (if LLs
    (mapcar 'reverse
      (mapcar 'cdr
        (mapcar 'reverse
          (mapcar 'ade_projptbackward LLs)
        );mapcar
      );mapcar
    );mapcar
  );if
);defun

(defun c:TEST ( / errMsg fPath coords)
  ;; Initial checks
  (setq errMsg
    (cond
      ((eq "" (getvar 'CGEOCS)) "\nDrawing must be Geo-Located.")
    );cond
  );setq
  (if errMsg (progn (alert (princ errMsg)) (exit)))
  (setq fPath "C:\\Users\\me\\Downloads\\output.csv")
  (if (setq coords (GetCoordData fPath))
    (progn
      (setq coords (LLs->PTs coords))
      (prompt "\nHere are your X/Y coordinates:\n")
      (print coords)
    );progn
  );if
  (princ)
);defun

 

Best,

~DD

Message 4 of 11

daniel_cadext
Advisor
Advisor

“py executable”

 

Far from my area of expertise, but I noticed your running a python script first, if you’re running vanilla AutoCAD, You might have a look at PyRx, as you can run Geopandas, Shapely, and GDAL directly inside AutoCAD.

 

I think you would use AcDbGeoData and AcDbGeoPositionMarker to setup the drawing. AcDbGeoData has functions to transform coordinate systems

Possible relevant links

 

https://www.theswamp.org/index.php?topic=59355.0

https://www.theswamp.org/index.php?topic=59548.0

https://www.theswamp.org/index.php?topic=58685.0

https://www.theswamp.org/index.php?topic=58613.0

 

Probably not trivial though

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 5 of 11

nicolasR6NGC
Contributor
Contributor

So I'm working in Civil but the lisp will be for AutoCAD LT.

0 Likes
Message 6 of 11

nicolasR6NGC
Contributor
Contributor

Thanks I didn't know these libraries are out there I much prefer to code in python than lisp.

0 Likes
Message 7 of 11

pendean
Community Legend
Community Legend

@nicolasR6NGC wrote:

So I'm working in Civil but the lisp will be for AutoCAD LT.


LISP in LT is limited: not all functions are available, you are more likely to hit a wall if the LISP author is a heavy VLAX coder

https://help.autodesk.com/view/ACDLT/2025/ENU/?guid=GUID-037BF4D4-755E-4A5C-8136-80E85CCEDF3E#:~:tex...

pendean_0-1731514394855.png

 

Message 8 of 11

Sea-Haven
Mentor
Mentor

Just a comment if your running CIV3D the import of Lat & Longs is a directly supported import method just need to add to the import type list it is there. I imported phone photos based on their georeference inside their jpg's.

 

Can you not do the import Lat & Long then save dwg what like 2 minutes work ? You then will have COGO points in a point group and can export the co-ordinates. "_AECCIMPORTPOINTS" is command add to a menu. 

0 Likes
Message 9 of 11

nicolasR6NGC
Contributor
Contributor

Oh that is really good to know thank you for calling this to my attention.

0 Likes
Message 10 of 11

nicolasR6NGC
Contributor
Contributor

I should have mentioned that I'm writing this in Civil for AutoCad LT to run, however this was my dynamo solution so it's helpful to know this is accessible in lisp as well.

0 Likes
Message 11 of 11

nicolasR6NGC
Contributor
Contributor

I think my solution for now will be to use python libraries (shapely, geopandas, pykml) to do everything and then reference the executable in lisp for autocad to run, however everyone's solutions were super helpful.

0 Likes