;;;; geopolygon.scm ;;;; Kon Lovett, May '17 ;;;; Kon Lovett, Aug '17 (module geopolygon (;export make-geopolygon geopolygon? check-geopolygon error-geopolygon geopolygon geopolygon-closed? geopolygon-open? geopolygon-bounding-box ) (import scheme) (import chicken) (use vector-lib) (use type-checks) (use geopoint geobox) ;;; ;not strict (define make-geopolygon (case-lambda ((gps) (cond ((vector? gps) gps ) ((list? gps) (list->vector gps) ) (else (warning 'make-geopolygon "unrecognized as geopolygon" gps) gps ) ) ) (rest (make-geopolygon rest) ) ) ) (define (geopolygon? obj) (and (vector? obj) (vector-every geopoint? obj)) ) (define-check+error-type geopolygon) (define (geopolygon . gps) (make-geopolygon gps) ) ; explicitly closed means [0] = [n-1] (define (geopolygon-closed? gpoly) (let* ((gpoly (if (list? gpoly) (list->vector gpoly) gpoly)) (len (vector-length gpoly)) ) (and (fx<= 2 len) (geopoint= (vector-ref gpoly 0) (vector-ref gpoly (fx- len 1))) ) ) ) ; explicitly open means [0] != [n-1] (define (geopolygon-open? gpoly) (not (geopolygon-closed? gpoly)) ) ;; (define (geopolygon-bounding-box gpoly) (let ((gpoly (if (list? gpoly) (list->vector gpoly) gpoly))) (check-geopolygon 'geopolygon-bounding-box gpoly) (let ((len (vector-length gpoly))) (let loop ((i 0) (minLat 90.0) (minLon 180.0) (maxLat -90.0) (maxLon -180.0)) (if (fx= i len) (make-geobox minLat minLon maxLat maxLon) (let* ((pnt (vector-ref gpoly i)) (lat (geopoint-latitude pnt) ) (lon (geopoint-longitude pnt) ) ) (loop (fx+ i 1) (min lat minLat) (min lon minLon) (max lat maxLat) (max lon maxLon)) ) ) ) ) ) ) ) ;geopolygon