;;; --------------------------------------------------------------------- ;;; SPOTPLOT-bgol.lsp ;;; Command: PSLV ;;; ;;; PURPOSE ;;; A CAD-native equivalent of the "Plot Spot Levels with Range ;;; Colour" Excel macro workflow: reads a CSV of survey points ;;; (X,Y,Z) directly inside the drawing, automatically buckets each ;;; point's elevation into one of several colour bands, plots the ;;; elevation as TEXT at its coordinate in the matching AutoCAD ;;; colour, and draws a simple colour-coded legend so terrain highs ;;; and lows are visible at a glance -- without ever leaving CAD or ;;; round-tripping through Excel. ;;; ;;; USAGE ;;; 1. Load this file (APPLOAD or drag-drop onto the drawing window). ;;; 2. Type PSLV at the command line and press Enter. ;;; 3. Select the source CSV file (rows: X,Y,Z). ;;; 4. Enter the number of colour bands (or accept the default, 5). ;;; 5. Enter the text height for the plotted elevation labels. ;;; 6. Pick the legend insertion point. ;;; 7. Elevation text is plotted at each point's X,Y coordinate in ;;; a colour matching its elevation band, all on layer ;;; "BGOL-PSLV"; a colour-coded legend is drawn at the picked ;;; point. ;;; ;;; NOTES ;;; - Colour bands are computed automatically: evenly spaced ;;; between the data's minimum and maximum elevation, using ;;; AutoCAD colour indices 1 (red) through 9 for up to 9 bands. ;;; - This is an original, independently written implementation. ;;; It is INSPIRED by the general idea of color-coded spot-level ;;; plotting utilities common in survey/earthwork workflows ;;; (typically distributed as spreadsheet macros), but the code, ;;; command name and file name here are new, entirely ;;; AutoLISP-native, 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:PSLV-EnsureLayer (lname / ) (if (not (tblsearch "LAYER" lname)) (entmake (list '(0 . "LAYER") '(100 . "AcDbSymbolTableRecord") '(100 . "AcDbLayerTableRecord") (cons 2 lname) '(70 . 0) '(62 . 7) '(6 . "Continuous"))) ) ) (defun BGOL:PSLV-Split (str delim / pos out remain) (setq out '()) (setq remain str) (while (setq pos (vl-string-search delim remain)) (setq out (append out (list (substr remain 1 pos)))) (setq remain (substr remain (+ pos 1 (strlen delim)))) ) (setq out (append out (list remain))) out ) (defun BGOL:PSLV-MakeText (pt txt height clr lname / dxfdata) (setq dxfdata (list '(0 . "TEXT") '(100 . "AcDbEntity") (cons 8 lname) (cons 62 clr) '(100 . "AcDbText") (cons 10 pt) (cons 40 height) (cons 1 txt) ) ) (entmake dxfdata) ) ;; Determine colour index (1-9) for value v given min/max/nbands. (defun BGOL:PSLV-BandColor (v vmin vmax nbands / span idx) (setq span (- vmax vmin)) (if (<= span 0.0) 1 (progn (setq idx (fix (* nbands (/ (- v vmin) span)))) (if (>= idx nbands) (setq idx (1- nbands))) (1+ (rem idx 9)) ) ) ) (defun C:PSLV ( / path f line fields x y z pts height nbands vmin vmax legpt i clr band bandmin bandmax legy rowh sw) (BGOL:PSLV-EnsureLayer "BGOL-PSLV") (setq path (getfiled "Select Spot Level Data File (X,Y,Z)" "" "csv;txt" 0)) (if path (progn (setq nbands (getint "\nNumber of colour bands <5>: ")) (if (not nbands) (setq nbands 5)) (setq height (getreal "\nText height <2.5>: ")) (if (not height) (setq height 2.5)) (setq f (open path "r")) (setq pts '()) (if f (progn (while (setq line (read-line f)) (if (and line (> (strlen (vl-string-trim " \t" line)) 0)) (progn (setq fields (BGOL:PSLV-Split line ",")) (if (>= (length fields) 3) (progn (setq x (atof (nth 0 fields))) (setq y (atof (nth 1 fields))) (setq z (atof (nth 2 fields))) (setq pts (append pts (list (list x y z)))) ) ) ) ) ) (close f) (if (> (length pts) 0) (progn (setq vmin (caddr (car pts))) (setq vmax vmin) (foreach p pts (setq z (caddr p)) (if (< z vmin) (setq vmin z)) (if (> z vmax) (setq vmax z)) ) (foreach p pts (setq clr (BGOL:PSLV-BandColor (caddr p) vmin vmax nbands)) (BGOL:PSLV-MakeText (list (car p) (cadr p) (caddr p)) (rtos (caddr p) 2 3) height clr "BGOL-PSLV") ) (setq legpt (getpoint "\nPick legend insertion point: ")) (if legpt (progn (setq rowh (* height 1.8)) (setq sw (* height 1.2)) (setq legy (cadr legpt)) (setq i 0) (while (< i nbands) (setq bandmin (+ vmin (* (- vmax vmin) (/ (float i) nbands)))) (setq bandmax (+ vmin (* (- vmax vmin) (/ (float (1+ i)) nbands)))) (setq clr (1+ (rem i 9))) (entmake (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") (cons 8 "BGOL-PSLV") (cons 62 clr) '(100 . "AcDbPolyline") '(90 . 4) '(70 . 1) (cons 10 (list (car legpt) legy)) (cons 10 (list (+ (car legpt) sw) legy)) (cons 10 (list (+ (car legpt) sw) (+ legy rowh))) (cons 10 (list (car legpt) (+ legy rowh))) ) ) (BGOL:PSLV-MakeText (list (+ (car legpt) sw (* height 0.6)) (+ legy (* rowh 0.25)) 0.0) (strcat (rtos bandmin 2 2) " - " (rtos bandmax 2 2)) (* height 0.85) 7 "BGOL-PSLV") (setq legy (- legy rowh)) (setq i (1+ i)) ) ) ) (princ (strcat "\nPSLV: " (itoa (length pts)) " spot level(s) plotted in " (itoa nbands) " colour band(s) on layer BGOL-PSLV.")) ) (princ "\nNo valid X,Y,Z rows found in the file.") ) ) (princ "\nCould not open the selected file.") ) ) (princ "\nNo file selected.") ) (princ) ) (princ "\nSPOTPLOT-bgol.lsp loaded. Type PSLV to plot colour-banded spot levels from a CSV file.") (princ "\n -- Free & open-source, courtesy of BGol Community (https://bgol.in/) --") (princ)