Author: hhubner Date: Mon Jan 21 06:10:27 2008 New Revision: 2371
Added: branches/bos/projects/bos/m2/geo-utm.lisp branches/bos/projects/bos/m2/geometry.lisp Modified: branches/bos/projects/bos/m2/bos.m2.asd branches/bos/projects/bos/m2/map.lisp branches/bos/projects/bos/m2/packages.lisp Log: Application-agnostic geometry functions should be put into geometry.lisp now, point-in-polygon-p has been moved. Add Common Lisp version of the Javascript UTM<->Lat/Lon converter, does not yet work.
Modified: branches/bos/projects/bos/m2/bos.m2.asd ============================================================================== --- branches/bos/projects/bos/m2/bos.m2.asd (original) +++ branches/bos/projects/bos/m2/bos.m2.asd Mon Jan 21 06:10:27 2008 @@ -3,19 +3,25 @@ (asdf:defsystem :bos.m2 :depends-on (:bknr :bknr-modules :net.post-office :cl-mime :iconv :kmrcl :iterate :arnesi) :components ((:file "packages") + (:file "geo-utm" :depends-on ("packages")) + (:file "geometry" :depends-on ("packages")) (:file "config" :depends-on ("packages")) (:file "utils" :depends-on ("config")) (:file "news" :depends-on ("poi")) (:file "tiled-index" :depends-on ("config")) (:file "mail-generator" :depends-on ("config")) (:file "make-certificate" :depends-on ("config")) - (:file "m2" :depends-on ("tiled-index" "utils" "make-certificate" "mail-generator")) + (:file "m2" :depends-on ("tiled-index" + "utils" + "make-certificate" + "mail-generator" + "geo-utm")) (:file "contract-expiry" :depends-on ("m2")) (:file "allocation" :depends-on ("m2")) - (:file "allocation-cache" :depends-on ("packages")) + (:file "allocation-cache" :depends-on ("packages" "geometry")) (:file "poi" :depends-on ("utils" "allocation")) (:file "bitmap" :depends-on ("allocation")) (:file "import" :depends-on ("m2")) - (:file "map" :depends-on ("m2" "allocation")) + (:file "map" :depends-on ("m2" "allocation" "geometry")) (:file "export" :depends-on ("m2")) (:file "cert-daemon" :depends-on ("config"))))
Added: branches/bos/projects/bos/m2/geo-utm.lisp ============================================================================== --- (empty file) +++ branches/bos/projects/bos/m2/geo-utm.lisp Mon Jan 21 06:10:27 2008 @@ -0,0 +1,152 @@ +(in-package :geo-utm) + +;; Converted from Javascript + +;; Origin: http:;;home.hiwaay.net/~taylorc/toolbox/geography/geoutm.html +;; Copyright 1997-1998 by Charles L. Taylor + +;; Page says: + +;; <P>Programmers: The JavaScript source code in this document may be copied +;; and reused without restriction.</P> + +(defconstant sm_a 6378137.0) +(defconstant sm_b 6356752.314) +(defconstant sm_EccSquared 6.69437999013e-03) + +(defconstant UTMScaleFactor 0.9996) + +(defun DegToRad (deg) + (* (/ deg 180.0) pi)) + +(defun RadToDeg (rad) + (/ rad (* pi 180.0))) + +(defun ArcLengthOfMeridian (phi) + (let* ((n (/ (- sm_a sm_b) (+ sm_a sm_b))) + (alpha (* (/ (+ sm_a sm_b) 2) + (+ 1 + (/ (expt n 2) 4) + (/ (expt n 4) 64)))) + (beta (+ (/ (* -3 n) 2) + (/ (* 9 (expt n 3)) 16) + (/ (* -3 (expt n 5)) 32))) + (gamma (+ (/ (* 15 (expt n 2)) 16) + (/ (* -15 (expt n 4)) 32))) + (delta (+ (/ (* -35 (expt n 3)) 48) + (/ (* 105 (expt n 5)) 256))) + (epsilon (/ (* 315 (expt n 4)) 512))) + (* alpha + (+ phi + (* beta (sin (* 2 phi))) + (* gamma (sin (* 4 phi))) + (* delta (sin (* 6 phi))) + (* epsilon (sin (* 8 phi))))))) + +(defun UTMCentralMeridian (zone) + (DegToRad (+ -183 (* zone 6)))) + +(defun FootpointLatitude (y) + (let* ((n (/ (- sm_a sm_b) (+ sm_a sm_b))) + (alpha (* (/ (+ sm_a sm_b) 2) + (+ 1 + (/ (expt n 2) 4) + (/ (expt n 4) 64)))) + (y (/ y alpha)) + (beta (+ (/ (* 3 n) 2) + (/ (* -27 (expt n 3)) 32) + (/ (* 269 (expt n 5) 512)))) + (gamma (+ (/ (* 21 (expt n 2)) 16) + (/ (* -55 (expt n 4)) 32))) + (delta (+ (/ (* 151 (expt n 3)) 96) + (/ (* -417 (expt n 5)) 128))) + (epsilon (/ (* 1097 (expt n 4)) 512))) + (+ y + (* beta (sin (* 2 y))) + (* gamma (sin (* 4 y))) + (* delta (sin (* 6 y))) + (* epsilon (sin (* 8 y)))))) + +(defun MapLatLonToXY (phi lambda lambda0) + (let* ((ep2 (/ (- (expt sm_a 2) (expt sm_b 2)) (expt sm_b 2))) + (nu2 (* ep2 (expt (cos phi) 2))) + (N (/ (expt sm_a 2) (* sm_b (sqrt (+ 1 nu2))))) + (t- (tan phi)) + (t2 (* t- t-)) + (l (- lambda lambda0)) + (l3coef (+ 1 (- t2) nu2)) + (l4coef (+ 5 (- t2) (* 9 nu2) (* 4 nu2 nu2))) + (l5coef (+ 5 (- (* 18 t2)) (* t2 t2) (* 14 nu2) (- (* 58 t2 nu2)))) + (l6coef (+ 61 (- (* 58 t2)) (* t2 t2) (* 270 nu2) (- (* 330 t2 nu2)))) + (l7coef (+ 61 (- (* 479 t2)) (* 179 t2 t2) (- (* t2 t2 t2)))) + (l8coef (+ 1385 (- (* 3111 t2)) (* 543 t2 t2) (- (* t2 t2 t2)))) + (easting (+ (* N (cos phi) l) + (/ N (* 6 (expt (cos phi) 3) l3coef (expt l 3))) + (/ N (* 120 (expt (cos phi) 5) l5coef (expt l 5))) + (/ N (* 5040 (expt (cos phi) 7) l7coef (expt l 7))))) + (northing (+ (ArcLengthOfMeridian phi) + (/ t- (* 2 N (expt (cos phi) 2) (expt l 2))) + (/ t- (* 24 N (expt (cos phi) 4) l4coef (expt l 4))) + (/ t- (* 720 N (expt (cos phi) 6) l6coef (expt l 6))) + (/ t- (* 40320 N (expt (cos phi) 8) l8coef (expt l 8)))))) + (list easting northing))) + +(defun MapXYToLatLon (x y lambda0) + (let* ((phif (FootpointLatitude y)) + (ep2 (/ (- (expt sm_a 2) (expt sm_b 2)) (expt sm_b 2))) + (cf (cos phif)) + (nuf2 (* ep2 (expt cf 2))) + (Nf (/ (expt sm_a 2) (* sm_b (sqrt (+ 1 nuf2))))) + (tf (tan phif)) + (tf2 (* tf tf)) + (tf4 (* tf2 tf2)) + (x1frac (/ 1.0 (* Nf cf))) + (x2frac (/ tf (* 2 (expt Nf 2)))) + (x3frac (/ 1.0 (* 6 (expt Nf 3) cf))) + (x4frac (/ tf (* 24 (expt Nf 4)))) + (x5frac (/ 1.0 (* 120 (expt Nf 5) cf))) + (x6frac (/ tf (* 720 (expt Nf 6)))) + (x7frac (/ 1.0 (* 5040 (expt Nf 7) cf))) + (x8frac (/ tf (* 40320 (expt Nf 8)))) + (x2poly (- -1 nuf2)) + (x3poly (- -1 (* 2 tf2) nuf2)) + (x4poly (+ 5 + (* 3 tf2) + (* 6 nuf2) + (- (* 6 tf2 nuf2)) + (- (* 3 nuf2 nuf2)) + (- (* 9 tf2 nuf2 nuf2)))) + (x5poly (+ 5 (* 28 tf2) (* 24 tf4) (* 6 nuf2) (* 8 tf2 nuf2))) + (x6poly (+ -61 (- (* 90 tf2)) (- (* 45 tf4)) (- (* 107 nuf2)) (* 162 tf2 nuf2))) + (x7poly (- 6 (* 662 tf2) (* 1320 tf4) (* 720 tf4 tf2))) + (x8poly (+ 1385 (* 3633 tf2) (* 4095 tf4) (* 1575 tf4 tf2))) + (latitude (+ phif + (* x2frac x2poly x x) + (* x4frac x4poly (expt x 4)) + (* x6frac x6poly (expt x 6)) + (* x8frac x8poly (expt x 8)))) + (longitude (+ lambda0 + (* x1frac x) + (* x3frac x3poly (expt x 3)) + (* x5frac x5poly (expt x 5)) + (* x7frac x7poly (expt x 7))))) + (list latitude longitude))) + +(defun lat-lon-to-utm-x-y (lat lon &optional (zone 50)) + ;; The Javascript version claims that the zone is calculated if not + ;; provided, but I could not find the code that does it. This + ;; should be added. This version of the code requires that the + ;; correct zone is provided. + (destructuring-bind (easting northing) + (MapLatLonToXY (DegToRad lat) (DegToRad lon) (UTMCentralMeridian zone)) + (list (+ (* easting UTMScaleFactor) 500000) + (+ (* northing UTMScaleFactor) + (if (minusp northing) 10000000 0)) + zone))) + +(defun utm-x-y-to-lat-lon (x y zone southhemi) + (destructuring-bind (lat lon) + (MapXYToLatLon (/ (- x 500000) UTMScaleFactor) + (/ (- y (if southhemi 10000000 0)) UTMScaleFactor) + (UTMCentralMeridian zone)) + (list (RadToDeg lat) (RadToDeg lon)))) \ No newline at end of file
Added: branches/bos/projects/bos/m2/geometry.lisp ============================================================================== --- (empty file) +++ branches/bos/projects/bos/m2/geometry.lisp Mon Jan 21 06:10:27 2008 @@ -0,0 +1,19 @@ + +(in-package :geometry) + +(defun point-in-polygon-p (x y polygon) + (let (result + (py y)) + (loop with (pjx . pjy) = (aref polygon (1- (length polygon))) + for (pix . piy) across polygon + when (and (or (and (<= piy py) (< py pjy)) + (and (<= pjy py) (< py piy))) + (< x + (+ (/ (* (- pjx pix) (- py piy)) + (- pjy piy)) + pix))) + do (setf result (not result)) + do (setf pjx pix + pjy piy)) + result)) +
Modified: branches/bos/projects/bos/m2/map.lisp ============================================================================== --- branches/bos/projects/bos/m2/map.lisp (original) +++ branches/bos/projects/bos/m2/map.lisp Mon Jan 21 06:10:27 2008 @@ -60,22 +60,6 @@ ;;;; kann, sie ist jedoch makrobasiert und nicht flexibel - Sie ;;;; erlaubt ausschlie�lich das Iterieren �ber ein Image.
-(defun point-in-polygon-p (x y polygon) - (let (result - (py y)) - (loop with (pjx . pjy) = (aref polygon (1- (length polygon))) - for (pix . piy) across polygon - when (and (or (and (<= piy py) (< py pjy)) - (and (<= pjy py) (< py piy))) - (< x - (+ (/ (* (- pjx pix) (- py piy)) - (- pjy piy)) - pix))) - do (setf result (not result)) - do (setf pjx pix - pjy piy)) - result)) - (defun colorize-pixel (pixel-rgb-value color-red color-green color-blue) "Colorize the given PIXEL-RGB-VALUE in the COLOR given. PIXEL-RGB-VALUE is a raw truecolor pixel with RGB components. COLOR
Modified: branches/bos/projects/bos/m2/packages.lisp ============================================================================== --- branches/bos/projects/bos/m2/packages.lisp (original) +++ branches/bos/projects/bos/m2/packages.lisp Mon Jan 21 06:10:27 2008 @@ -1,5 +1,14 @@ (in-package :cl-user)
+(defpackage :geometry + (:use :cl) + (:export #:point-in-polygon-p)) + +(defpackage :geo-utm + (:use :cl) + (:export #:lat-lon-to-utm-x-y + #:utm-x-y-to-lat-lon)) + (defpackage :bos.m2.config (:export #:+width+ #:+nw-utm-x+ @@ -27,6 +36,7 @@ (:use :cl :cl-ppcre :cl-interpol + :geometry :bknr.utils :bknr.indices :bknr.datastore @@ -211,12 +221,9 @@ (:shadowing-import-from :cl-interpol #:quote-meta-chars) (:export #:cert-daemon))
-;;; maybe there is a nicer way to do this -;;; if you want to test this run ./build.sh at least twice ! -(intern "POINT-IN-POLYGON-P" :bos.m2) - (defpackage :bos.m2.allocation-cache - (:use :cl + (:use :cl + :geometry :bknr.indices :bknr.datastore :bknr.user @@ -227,10 +234,10 @@ :bos.m2.config :iterate :arnesi) - (:import-from :bos.m2 bos.m2::point-in-polygon-p) (:export #:find-exact-match #:add-area #:free-regions-count #:free-regions-pprint #:rebuild-cache #:allocation-cache-subsystem)) +