I've changed your home road.csv - added "," as separator, and my first code for drawing peace of Earth ground on sphere did the job, but second code gave wrong results, as there were many soilds that were unable to be unioned and after that intersect with sphere anvelope with 1m thick shell...
Here are my codes and your csv - modified by me...
Regards, M.R.
P.S. I've used Evgeniy Elpanov's triangulation for determining area code, but no use on your example, you must find some other way to determine area...
Code:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; gpspronsph function takes GPS coordinates from CSV file, ;;; ;;; and project between points edges as arcs on sphere with radius of planet Earth. ;;; ;;; ;;; ;;; 25.07.2012. Marko Ribar, d.i.a. - first and final release ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun c:gpspronsph ( / file f csvrow Latt Long gpsdata ER ptx pty ptz pt ptlst k p1 p2 pm pmv1 pmsph ) (vl-cmdf "_.UCS" "w") (if (ssget "_X") (progn (alert "\nDWG must be empty - empty it and start over") (exit) ) ) (setq file (getfiled "Select file with GPS coordiantes" "" "csv" 2)) (setq f (open file "r")) (while (setq csvrow (read-line f)) (setq Latt (substr csvrow 1 (vl-string-position (ascii ",") csvrow))) (setq Long (substr csvrow (+ (vl-string-position (ascii ",") csvrow) 2) (- (strlen csvrow) (vl-string-position (ascii ",") csvrow) 1))) (setq gpsdata (cons (list (read Latt) (read Long)) gpsdata)) ) (setq gpsdata (reverse gpsdata)) (setq ER 6371000.0) ; Radius of Earth in m (foreach gps gpsdata (setq Latt (car gps)) (setq Long (cadr gps)) (setq ptx (* ER (cos (cvunit Latt "degrees" "radians")) (cos (cvunit Long "degrees" "radians")))) (setq pty (* ER (cos (cvunit Latt "degrees" "radians")) (sin (cvunit Long "degrees" "radians")))) (setq ptz (* ER (sin (cvunit Latt "degrees" "radians")))) (setq pt (list ptx pty ptz)) (setq ptlst (cons pt ptlst)) ) (setq ptlst (reverse ptlst)) (setq k -1) (repeat (length ptlst) (setq p1 (nth (setq k (1+ k)) ptlst)) (if (/= k (- (length ptlst) 1)) (setq p2 (nth (+ k 1) ptlst)) (setq p2 (car ptlst)) ) (setq pm (mapcar '(lambda ( a b ) (/ (+ a b) 2.0)) p1 p2)) (setq pmv1 (mapcar '(lambda ( a ) (/ a (distance '(0.0 0.0 0.0) pm))) pm)) (setq pmsph (mapcar '(lambda ( a ) (* a ER)) pmv1)) (vl-cmdf "_.UCS" "3" '(0.0 0.0 0.0) p1 p2) (vl-cmdf "_.ARC" (trans p1 0 1) "s" (trans pmsph 0 1) (trans p2 0 1)) (vl-cmdf "_.UCS" "p") ) (vl-cmdf "_.ZOOM" "_E") (princ) )Code:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; ;;; gpsareasph function takes GPS coordinates from CSV file, ;;; ;;; and project between points edges as arcs on sphere with radius of planet Earth, ;;; ;;; then it asks for offset distance to determine contour shape of peace of ground, ;;; ;;; for witch if finds approx. correct area value. ;;; ;;; 25.07.2012. Marko Ribar, d.i.a. - first and final release ;;; ;;; ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (vl-load-com) ;;********************************************************; ;; ; ;; Written by ElpanovEvgeniy ; ;; 17.10.2008 ; ;; edit 20.05.2011 ; ;; Program triangulate an irregular set of 3d points. ; ;; Modified by ymg June 2011 ; ;;********************************************************; (defun triangulate (pl / a b c i i1 i2 bb sl al el tl l ma mi ti tr x1 x2 y1 y2 p r cp ) (if pl (progn (setq ti (car (_VL-TIMES)) i 1 i1 (/ (length pl) 100.) i2 0 pl (vl-sort pl (function (lambda (a b) (< (car a) (car b)))) ) bb (list (apply 'mapcar (cons 'min pl)) (apply 'mapcar (cons 'max pl)) ) ;Replaced code to get minY and maxY with 3d Bounding Box Routine; ;A bit slower but clearer. minZ and maxZ kept for contouring ; x1 (caar bb) ;minX x2 (caadr bb) ;maxX y1 (cadar bb) ;minY y2 (cadadr bb) ;maxY ) (setq cp (list (/ (+ x1 x2) 2.0) (/ (+ y1 y2) 2.0)); Midpoint of points cloud and center point of circumcircle through supertriangle. r (* (distance cp (list x1 y1)) 20) ;This could still be too small in certain case. No harm if we make it bigger. ma (+ (car cp) r);ma is maxX of supertriangle mi (- (car cp) r);mi is minX of supertriangle sl (list (list ma (cadr cp) 0);list of 3 points defining the supertriangle (list mi (+ (cadr cp) r) 0) (list mi (- (cadr cp) r) 0) ) al (list (cons x2 (cons cp (cons (* 20 r) sl)))) ;al is a work list that contains active triangles each item is a list that contains: ; ; item 0: Xmax of points in triangle. ; ; item 1: List 2d coordinates of center of circle circumscribing triangle. ; ; item 2: Radius of above circle. ; ; item 3: List of 3 points defining the triangle ; ma (1- ma);Reducing ma to prepare for removal of triangles having a vertex mi (1+ mi);common with supertriangle. Done once triangulation is completed. ) ;Increasing mi for same reason. ;Begin insertion of points (repeat (length pl) (setq p (car pl);Get one point from point list pl (cdr pl);Remove point from point list el nil ;Initialize edge list ) (while al ;Active triangle list (setq tr (car al);Get one triangle from active triangle list. al (cdr al);Remove the triangle from the active list. ) (cond ((< (car tr) (car p)) (setq tl (cons (cdddr tr) tl)));This triangle inactive. We store it's 3 vertex in tl (Final triangle list). ((< (distance p (cadr tr)) (caddr tr));p is inside the triangle. (setq tr (cdddr tr) ;Trim tr to vertex of triangle only. a (car tr) ; First point. b (cadr tr) ; Second point. c (caddr tr) ; Third point. el (cons (list (+ (car a) (car b)) ;We create 3 new edges ab, bc and ca, (+ (cadr a) (cadr b)) ;and store them in edge list. a b ) (cons (list (+ (car b) (car c)) (+ (cadr b) (cadr c)) b c ) (cons (list (+ (car c) (car a)) (+ (cadr c) (cadr a)) c a ) el ) ) ) ) ) (t (setq l (cons tr l))) ;tr did not meet any cond so it is still active. ) ;we store it a temporary list. );Go to next triangle of active list. (setq al l ;Restore active triangle list from the temporary list. l nil ;Re-initialize the temporary list to prepare for next insertion. el (vl-sort el ;Sort the edges list on X and Y (function (lambda (a b) (if (= (car a) (car b)) (<= (cadr a) (cadr b)) (< (car a) (car b)) ) ) ) ) ) ;Removes doubled edges, form new triangles, calculates circumcircles and add them to active list. (while el (if (and (= (caar el) (caadr el)) (= (cadar el) (cadadr el)) ) (setq el (cddr el)) (setq al (cons (getcircumcircle p (cddar el)) al) el (cdr el) ) ) ) ;Spinner to show progress (if (and (< (setq i (1- i)) 1) (< i2 100)) (progn (setvar "MODEMACRO" (strcat " " (itoa (setq i2 (1+ i2))) " % " (substr "||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||" 1 i2 ) (substr "..." 1 (- 100 i2)) ) ) (setq i i1) ) ) ) ;Go to insert next point. ;We are done with the triangulation (foreach tr al (setq tl (cons (cdddr tr) tl)));What's left in active list is added to triangle list ;Purge triangle list of any triangle that has a common vertex with supertriangle. (setq tl (vl-remove-if-not (function (lambda (a) (and (< mi (caadr a) ma) (< mi (caaddr a) ma)) ) ) tl ) ) (foreach tr tl (vl-cmdf "_.UCS" "3" (car tr) (cadr tr) (caddr tr)) (vl-cmdf "_.PLINE" (trans (car tr) 0 1) (trans (cadr tr) 0 1) (trans (caddr tr) 0 1) "c" "") (vl-cmdf "_.UCS" "p") ) ) ) (setvar "MODEMACRO" "") (princ (strcat "\n " (rtos (/ (- (car (_VL-TIMES)) ti) 1000.) 2 4) " secs." ) ) (princ) ) ;;*********************************************************; ;; ; ;; Written by ElpanovEvgeniy ; ;; 17.10.2008 ; ;; Calculation of the centre of a circle and circle radius ; ;; for program triangulate ; ;; ; ;; Modified ymg june 2011 (renamed variables) ; ;;*********************************************************; (defun getcircumcircle (a el / b c c2 cp r ang) (setq b (car el) c (cadr el) c2 (list (car c) (cadr c)) ;c2 is point c but in 2d ) (if (not (zerop (setq ang (- (angle b c) (angle b a))) ) ) (progn (setq cp (polar c2 (+ -1.570796326794896 (angle c a) ang) (setq r (/ (distance a c2) (sin ang) 2.0)) ) r (abs r) ) (list (+ (car cp) r) cp r a b c) ) ) ) (defun c:gpsareasph ( / osm plt file f csvrow Latt Long gpsdata ER ptx pty ptz pt ptlst sph1 sph2 sph ptt plptlst pl pln ss dst +dp -dp dd n ent entt sss ar ) (vl-cmdf "_.UCS" "w") (if (ssget "_X") (progn (alert "\nDWG must be empty - empty it and start over") (exit) ) ) (setq osm (getvar 'osmode)) (setq plt (getvar 'plinetype)) (setvar 'osmode 0) (setvar 'plinetype 2) (setq file (getfiled "Select file with GPS coordiantes" "" "csv" 2)) (setq f (open file "r")) (while (setq csvrow (read-line f)) (setq Latt (substr csvrow 1 (vl-string-position (ascii ",") csvrow))) (setq Long (substr csvrow (+ (vl-string-position (ascii ",") csvrow) 2) (- (strlen csvrow) (vl-string-position (ascii ",") csvrow) 1))) (setq gpsdata (cons (list (read Latt) (read Long)) gpsdata)) ) (setq gpsdata (reverse gpsdata)) (setq ER 6371000.0) ; Radius of Earth in m (foreach gps gpsdata (setq Latt (car gps)) (setq Long (cadr gps)) (setq ptx (* (- ER 1.0) (cos (cvunit Latt "degrees" "radians")) (cos (cvunit Long "degrees" "radians")))) (setq pty (* (- ER 1.0) (cos (cvunit Latt "degrees" "radians")) (sin (cvunit Long "degrees" "radians")))) (setq ptz (* (- ER 1.0) (sin (cvunit Latt "degrees" "radians")))) (setq pt (list ptx pty ptz)) (setq ptlst (cons pt ptlst)) ) (setq ptlst (reverse ptlst)) (vl-cmdf "_.SPHERE" '(0.0 0.0 0.0) ER) (setq sph1 (entlast)) (vl-cmdf "_.SPHERE" '(0.0 0.0 0.0) (- ER 1.0)) (setq sph2 (entlast)) (vl-cmdf "_.SUBTRACT" sph1 "" sph2 "") (setq sph (entlast)) (vl-cmdf "_.PLAN" "") (triangulate ptlst) (gc) (foreach pt ptlst (setq ptt (list (car pt) (cadr pt) 0.0)) (setq plptlst (cons ptt plptlst)) ) (setq plptlst (reverse plptlst)) (setq pl (entmakex (append (list '(0 . "LWPOLYLINE") '(100 . "AcDbEntity") '(100 . "AcDbPolyline") (cons 90 (length plptlst)) '(70 . 1) ) (mapcar '(lambda ( x ) (cons 10 x)) plptlst) (list '(210 0.0 0.0 1.0)) ) ) ) (initget 2) (setq dd (getreal "\nType offset distance for determining contour shape of GPS area - if not correct enter (-10.0) <10.0> : ")) (if (null dd) (setq dd 10.0)) (setq pln (vlax-vla-object->ename (car (vlax-safearray->list (vlax-variant-value (vla-offset (vlax-ename->vla-object pl) dd)))))) (setq ptlst (mapcar 'cdr (vl-remove-if-not '(lambda ( a ) (eq (car a) 10)) (entget pln)))) (entdel pl) (entdel pln) (setq ss (ssget "_CP" (cons (car ptlst) (reverse ptlst)) '((0 . "LWPOLYLINE")))) (vl-cmdf "_.REGION" ss "") (setq ss (ssget "_X" '((0 . "REGION")))) (setq dst 100000.0) (setq +dp (/ dst 2.0)) (setq -dp (- +dp)) (setq sss (ssadd)) (repeat (setq n (sslength ss)) (setq ent (ssname ss (setq n (1- n)))) (setq entt (vlax-vla-object->ename (vla-copy (vlax-ename->vla-object ent)))) (vl-cmdf "_.EXTRUDE" ent "" +dp) (setq ent (entlast)) (vl-cmdf "_.EXTRUDE" entt "" -dp) (setq entt (entlast)) (vl-cmdf "_.UNION" ent entt "") (ssadd (entlast) sss) ) (vl-cmdf "_.UNION" sss "") (vl-cmdf "_.INTERSECT" sph (entlast) "") (vl-cmdf "_.ZOOM" "_E") (vl-cmdf "_.ERASE" (ssget "_X" '((0 . "LWPOLYLINE"))) "") (setq ar (vla-get-volume (vlax-ename->vla-object (entlast)))) (prompt "\nArea between GPS coordinates is : ") (princ ar) (prompt " square meters") (setvar 'osmode osm) (setvar 'plinetype plt) (princ) )




Reply With Quote


Bookmarks