;;; ---------------------------------------------------------------------
;;;  AREAUNITS-bgol.lsp
;;;  Command:  ARU
;;;
;;;  PURPOSE
;;;  Selects a closed polyline (polygon) and reports its area in six
;;;  commonly used units at once: Square Meters, Square Inch, Square
;;;  Feet, Square Yards, Acres and Hectares. Removes the need to
;;;  manually run separate unit conversions when a plot/parcel area must
;;;  be quoted in more than one measurement system.
;;;
;;;  USAGE
;;;    1. Load this file (APPLOAD or drag-drop onto the drawing window).
;;;    2. Type   ARU   at the command line and press Enter.
;;;    3. Select a closed LWPOLYLINE.
;;;    4. A small floating results panel lists the area converted into
;;;       all six units; the values are also printed to the command
;;;       line, and the polygon is labeled at its centroid on layer
;;;       "BGOL-ARU".
;;;
;;;  NOTES
;;;    - Area is read directly from the polyline via vlax-curve-getArea,
;;;      which returns drawing units squared; this routine assumes the
;;;      drawing's base unit is meters (typical metric survey setup).
;;;    - This is an original, independently written implementation.
;;;      It is INSPIRED by the general idea of multi-unit area reporting
;;;      utilities common in CAD/survey drafting workflows, but the
;;;      code, command name and file name here are new and are NOT
;;;      copied from, nor identical to, any specific third-party
;;;      product.
;;;
;;;  ---------------------------------------------------------------------
;;;  Developed and shared for the CAD community by:  BGol Community
;;;  Community website:                              https://bgol.in/
;;;  License:  Open-source & free to use, modify, and share for all.
;;;            Provided "as is", without warranty of any kind.
;;;  ---------------------------------------------------------------------

(vl-load-com)

(defun BGOL:ARU-EnsureLayer (lname / )
  (if (not (tblsearch "LAYER" lname))
    (entmake (list '(0 . "LAYER")
                   '(100 . "AcDbSymbolTableRecord")
                   '(100 . "AcDbLayerTableRecord")
                   (cons 2 lname)
                   '(70 . 0)
                   '(62 . 5)          ; blue
                   '(6 . "Continuous")))
  )
)

(defun BGOL:ARU-Centroid (obj / n i vlist pt sumx sumy)
  (setq sumx 0.0 sumy 0.0 n 0 i 0)
  (while (setq pt (vl-catch-all-apply 'vlax-curve-getPointAtParam (list obj (float i))))
    (if (not (vl-catch-all-error-p pt))
      (progn
        (setq sumx (+ sumx (car pt)))
        (setq sumy (+ sumy (cadr pt)))
        (setq n (1+ n))
      )
    )
    (setq i (1+ i))
    (if (> i 200) (setq pt nil))
  )
  (if (> n 0)
    (list (/ sumx n) (/ sumy n) 0.0)
    (list 0.0 0.0 0.0)
  )
)

(defun BGOL:ARU-MakeLabel (pt txt lname / )
  (entmake (list '(0 . "TEXT")
                 '(100 . "AcDbEntity")
                 (cons 8 lname)
                 '(100 . "AcDbText")
                 (cons 10 pt)
                 (cons 40 2.5)
                 (cons 1 txt)))
)

(defun C:ARU ( / ent obj closed area sqin sqft sqyd ac ha msg cen)
  (BGOL:ARU-EnsureLayer "BGOL-ARU")
  (setq ent (car (entsel "\nSelect closed polyline: ")))
  (if ent
    (progn
      (setq closed (= 1 (logand 1 (cdr (assoc 70 (entget ent))))))
      (if (not closed)
        (princ "\nWarning: selected polyline is not closed; area may be inaccurate.")
      )
      (setq obj (vlax-ename->vla-object ent))
      (setq area (vlax-curve-getArea obj))
      (setq sqin (* area 1550.0031))
      (setq sqft (* area 10.7639))
      (setq sqyd (* area 1.19599))
      (setq ac   (* area 0.000247105))
      (setq ha   (* area 0.0001))
      (setq cen (BGOL:ARU-Centroid obj))
      (BGOL:ARU-MakeLabel cen (strcat (rtos area 2 4) " sqm") "BGOL-ARU")
      (setq msg (strcat
                  "\nArea Report (BGOL ARU)"
                  "\n  Square Meters = " (rtos area 2 4)
                  "\n  Square Inch   = " (rtos sqin 2 4)
                  "\n  Square Feet   = " (rtos sqft 2 4)
                  "\n  Square Yards  = " (rtos sqyd 2 4)
                  "\n  Acres         = " (rtos ac 2 4)
                  "\n  Hectares      = " (rtos ha 2 4)
                ))
      (princ msg)
      (alert (strcat "Area\n"
                      "Square Meters = " (rtos area 2 4) "\n"
                      "Square Inch = " (rtos sqin 2 4) "\n"
                      "Square Feet = " (rtos sqft 2 4) "\n"
                      "Square Yards = " (rtos sqyd 2 4) "\n"
                      "Acres = " (rtos ac 2 4) "\n"
                      "Hectares = " (rtos ha 2 4)))
    )
    (princ "\nNo entity selected.")
  )
  (princ)
)

(princ "\nAREAUNITS-bgol.lsp loaded. Type ARU to report a polygon's area in six units.")
(princ "\n  -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --")
(princ)
