;;;; geopolygon.scm -*- Scheme -*- ;;;; Kon Lovett, Jul '18 ;;;; Kon Lovett, Aug '17 ;;;; Kon Lovett, May '17 (module geopolygon (;export make-geopolygon geopolygon? check-geopolygon error-geopolygon geopolygon geopolygon-closed? geopolygon-open? geopolygon-bounding-box ) (import scheme (chicken base) (chicken fixnum) (chicken type) vector-lib type-checks geopoint geobox) (include "geo-constants") ;;; (define (ensure-vector gps) (if (list? gps) (list->vector gps) gps) ) ;;; (define-type geopolygon (or (vector-of (struct geopoint)) (list-of (struct geopoint)))) ;; ;not strict (define make-geopolygon (case-lambda ((gps) (cond ((vector? gps) (and (vector-every geopoint? gps) gps ) ) ((list? gps) (make-geopolygon (ensure-vector gps)) ) (else (error 'make-geopolygon "unrecognized as geopolygon" gps) ) ) ) (rest (make-geopolygon rest) ) ) ) (: geopolygon? (* --> boolean)) ; (define (geopolygon? obj) (and (vector? obj) (vector-every geopoint? obj)) ) (define-check+error-type geopolygon) (: geopolygon (#!rest --> geopolygon)) ; (define (geopolygon . gps) (make-geopolygon gps) ) ; explicitly closed means [0] = [n-1] (: geopolygon-closed? (geopolygon --> boolean)) ; (define (geopolygon-closed? gpoly) (let* ( (gpoly (ensure-vector 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] (: geopolygon-open? (geopolygon --> boolean)) ; (define (geopolygon-open? gpoly) (not (geopolygon-closed? gpoly)) ) ;; (: geopolygon-bounding-box (geopolygon --> (struct geobox))) ; (define (geopolygon-bounding-box gpoly) (let* ( (gpoly (ensure-vector gpoly)) (len (vector-length (check-geopolygon 'geopolygon-bounding-box gpoly))) ) (let loop ((i 0) (minLat 90.0) (maxLat -90.0) (minLon 180.0) (maxLon -180.0)) ;traced polygon? (if (fx= i len) ;then report (make-geobox minLat minLon maxLat maxLon) ;else next point in poly (let* ( (pnt (vector-ref gpoly i)) (lat (geopoint-latitude pnt)) (lon (geopoint-longitude pnt)) ) (loop (fx+ i 1) (min lat minLat) (max lat maxLat) (min lon minLon) (max lon maxLon)) ) ) ) ) ) ) ;geopolygon