Extract Latitude and Longitude of objects as object data

akitchensZEZPR
Enthusiast
Enthusiast

Extract Latitude and Longitude of objects as object data

akitchensZEZPR
Enthusiast
Enthusiast

I want to extract the latitude and longitude of objects as data so that I can include it as object data attributes. Unfortunately, the properties window only gives the X and Y positions from the drawing geometry. The latitude and longitude show up in the task bar only, and appears to only be associated with the cursor position, not the objects.


I am creating a LISP to populate the blocks with object data attributes, and I really want to be able to include the lat and long in the code.


Right now we are going through a convoluted process of exporting the points to Google Earth, then converting the KMZ into a CSV, then importing it back into AutoCAD. It would be better to simply pull the lat and long directly from the features inside the drawing. The information is clearly there, I just don't know how to access it.  (We are using AutoCAD Map3D 2024)

LATLONG01.pngLATLONG02.png

0 Likes
Reply
473 Views
3 Replies
Replies (3)

CodeDing
Advisor
Advisor

@akitchensZEZPR ,

 

Here are some functions you can use. They convert single points to Lat/Longs, List of Points to Lat/Long, single Lat/Long to point, and List of Lat/Longs to points.

 

You can see more about ADE Functions here:

https://documentation.help/AutoCAD-Map-3D-2009-AutoLISP/documentation.pdf 

 

Functions for you [you should add your own checks to ensure your DWG is Geo-Located first, e.g. (getvar 'CGEOCS)]:

;; Turns a point into (long lat) point ..ONLY useable if dwg is Geo-Located.
;; pt - point, 
;; returns - point, as (Long Lat) ...since longitudes represent "x" values & Latitudes represent "y" values
(defun PT->LL (pt / )
  (ade_projsetsrc (getvar 'CGEOCS))
  (ade_projsetdest "LL84")
  (if pt
    (reverse (cdr (reverse (ade_projptforward pt))))
  );if
);defun

;; Turns many points into (long lat) points ..ONLY useable if dwg is Geo-Located.
;; pts - list, of points 
;; returns - list, as ((Long Lat) ...) ...since longitudes represent "x" values & Latitudes represent "y" values
(defun PTs->LLs (pts / )
  (ade_projsetsrc (getvar 'CGEOCS))
  (ade_projsetdest "LL84")
  (if pts
    (mapcar 'reverse
      (mapcar 'cdr
        (mapcar 'reverse
          (mapcar 'ade_projptforward pts)
        );mapcar
      );mapcar
    );mapcar
  );if
);defun

;; Turns a (long lat) into coordinates ..ONLY useable if dwg is Geo-Located.
;; pt - point as (long lat), 
;; returns - point, as (X Y) ...since longitudes represent "x" values & Latitudes represent "y" values
(defun LL->PT (LL / )
  (ade_projsetsrc (getvar 'CGEOCS))
  (ade_projsetdest "LL84")
  (if LL
    (reverse (cdr (reverse (ade_projptbackward LL))))
  );if
);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

 


Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
0 Likes

CodeDing
Advisor
Advisor

@akitchensZEZPR ,

 

Your workflow might look like this:

 

(defun c:TEST ( / PT->LL ePnt eBlk pt LL)
  ;; Helper Function
  (defun PT->LL (pt / )
    (ade_projsetsrc (getvar 'CGEOCS))
    (ade_projsetdest "LL84")
    (if pt
      (reverse (cdr (reverse (ade_projptforward pt))))
    );if
  );defun
  ;; Begin Work
  (if (and (setq ePnt (car (entsel "\nSelect Point: ")))
           (eq "POINT" (cdr (assoc 0 (entget ePnt))))
           (setq eBlk (car (entsel "\nSelect Block: ")))
           (eq "INSERT" (cdr (assoc 0 (entget eBlk))))
      );and
    (progn
      (setq pt (cdr (assoc 10 (entget ePnt))))
      (setq LL (PT->LL pt))
      ;; [you should, ideally, check for Object Data table & field existence before setting field]
      (ade_odsetfield eBlk "ATT" "X" 0 (rtos (car LL) 2 7))
      (ade_odsetfield eBlk "ATT" "Y" 0 (rtos (cadr LL) 2 7))
      (prompt "\nObject Data fields set successfully.")
    );progn
  ;else
    (prompt "\nAn incorrect entity was selected, no actions performed.")
  );if
  (princ)
);defun

 

...Or this...

(defun c:TEST ( / PT->LL odTableName odFieldName1 odFieldName2 errMsg ePnt eBlk pt LL)
  ;; Helper Function
  (defun PT->LL (pt / )
    (ade_projsetsrc (getvar 'CGEOCS))
    (ade_projsetdest "LL84")
    (if pt
      (reverse (cdr (reverse (ade_projptforward pt))))
    );if
  );defun
  ;; Initial Checks
  (setq odTableName "ATT")
  (setq odFieldName1 "X" odFieldName2 "Y")
  (setq errMsg
    (cond
      ((eq "" (getvar 'CGEOCS)) "\nDrawing must be Geo-Located.")
      ((or (not (setq ePnt (car (entsel "\nSelect Point: "))))
           (not (eq "POINT" (cdr (assoc 0 (entget ePnt))))))
        "\nA Point was not selected."
      )
      ((or (not (setq eBlk (car (entsel "\nSelect Block: "))))
           (not (eq "INSERT" (cdr (assoc 0 (entget eBlk))))))
        "\nA Block was not selected."
      )
      ((not (member odTableName (ade_odgettables eBlk)))
        (strcat "\nThe OD table, " odTableName ", is not attached to the block.")
      )
    );cond
  );setq
  (if errMsg
    (progn (alert (princ errMsg)) (exit))
  );if
  ;; Begin Work
  (setq pt (cdr (assoc 10 (entget ePnt))))
  (setq LL (PT->LL pt))
  (ade_odsetfield eBlk odTableName odFieldName1 0 (rtos (car LL) 2 7))
  (ade_odsetfield eBlk odTableName odFieldName2 0 (rtos (cadr LL) 2 7))
  (prompt "\nObject Data fields set successfully.")
  (princ)
);defun

Best,

~DD


Need AutoLisp help? Try my custom GPT 'AutoLISP Ace':
https://chat.openai.com/g/g-Zt0xFNpOH-autolisp-ace
0 Likes

ChicagoLooper
Mentor
Mentor

Hi @akitchensZEZPR 

You can easily do it using DATAEXTRACTION command....but there's a catch. You must do it using the Map Task Pane, on Map Explorer Tab (in other words you will need to perform a Query).

 

Since you are already getting the Lat/Long from the Task Bar, your drawing must already have a properly Assigned Coordinate System. If it is a valid CS for your site then you can use DATEXTRACTION. Here are the instructions.

 

Before you begin...

  • Make sure your drawing has a properly assigned Coordinate System. Don't assign a coordinate system that's perfect for New Zealand if your site is in the USA, that CS  is only good for that part of Planet Earth and it isn't a 'proper CS' for your site's location. If you site is in the US, your assigned CS will have units in feet and that's OK even though you want to determine the corresponding coordinates in DEGREES.
  • Make sure you CLOSE your original drawing. Your drawing MUST BE CLOSED to run a Query because Map3D won't execute your query if your original is still open.

1.  To begin, open a clean, brand new drawing, either imperial or metric, whichever is applicable. On command line type in UNITS. Change the Precision (under the Length section) to 6 or more decimal places. This will allow you to obtain accurate Lat/Longs (6 decimals minimum) when you perform DATAEXTRACTION later on. 

<<NOTE: If you wish, you may increase precision to more than 6 decimals places. Six decimals is the minimum.>>

Image-1Image-1

 

2. In this new drawing enter MAPCSASSIGN on command line. Search using LL83=>select EPSG 4269=>Assign. 

NOTE: You are assigning EPSG 4269 because you want the coordinates to have units of DEGREES, not feet.

Image-2Image-2

<<Alternatively, you may also use LL84, EPSG 4326 to determine the Lat/Long.>>

 

3. On command line enter MAPWSPACE=>Select 'ON' (from options on command line)=>Go to Map Explorer Tab=>Drag-and-Drop. From your project folder, DRAG the original drawing from its folder=>DROP it onto a blank, empty area of the Map Explorer Tab.

<< Hint: If your original drawing is LARGE, drag it slowly then wait at least 4 seconds b-e-f-o-r-e dropping it on Map Explorer.>>   

Image-3Image-3

 

4. Next, you will BUILD your query. Right-click Current query=>Define.

Image-4Image-4

 

5. Establish the parameters of your query by following the steps shown below. NOTE: This query, your query, is simple, super simple, because all you want to do is add OBJECTS from the original drawing to this new one. The query can also (a) add specific objects, (b) add objects only from specific locations in the original dwg, or (c) both a and b. Depending on your creativity and know-how, a query can even do more than a, b, and c. Lots of horsepower!!

<<If you need a more sophisticated query, please start a new post.>>Image-5Image-5

6. After EXECUTE QUERY, zoom extents to see the query results. Finally,detach your original drawing. While the drawing is 'attached' to the Map Explorer Tab, Map3D 'locks' it down. By detaching, the drawing will be unlocked. Map3D cannot open a locked dwg.

Image-6Image-6

 

Finally, perform DATAEXTRACTION to pull out the X/Y coordinates, Lat and Long respectively, their units will automatically be in DEGREES. Why? Because earlier you assigned  a CS with units of Degrees (EPSG 4269).

<<The DataExtraction command is not covered in this post.>>

Chicagolooper

EESignature