draw a map of cities from a list of coordinates pasted by C-Keen on Thu Jan 26 12:42:33 2012

(use doodle)


(define cities (with-input-from-file "staedte.sexpr" read))

(define coord second)
(define get-x first)
(define get-y second)
(define-constant +width+ 680)
(define-constant +height+ 460)

(define blue (list 0 0 1 1))

(new-doodle background: solid-white)

(define min-x (fold (lambda (c s) (min s (get-x (coord c)))) most-positive-fixnum cities))
(define max-x (fold (lambda (c s) (max s (get-x (coord c)))) 0 cities))

(define min-y (fold (lambda (c s) (min s (get-y  (coord c)))) most-positive-fixnum cities))
(define max-y (fold (lambda (c s) (max s (get-y  (coord c)))) 0 cities))

(define (scale val min max mapped-min mapped-max)
  (* (+ mapped-min (- mapped-max mapped-min))
     (/ (- val min)
        (- max min))))

(print "min-x: " min-x ", max-x: " max-x ", min-y: " min-y ", max-y: " max-y)

(for-each (lambda (c) (let* ((xy (coord c))
                             (x (get-x xy))
                             (y (get-y xy))
                             (scaled-x (scale x min-x max-x +width+ +height+))
                             (scaled-y (scale y min-y max-y +width+ +height+)))
                        (circle scaled-x (- +height+ scaled-y) 1 blue)))
          cities)

(show!)
(save-screenshot "germany.png")


; See http://pestilenz.org/~ckeen/germany.png

now with mercator projection (thanks wikipedia) pasted by C-Keen on Thu Jan 26 14:40:24 2012

(use doodle)

(define cities (with-input-from-file "staedte.sexpr" read))

(define coord second)
(define get-x first)
(define get-y second)
(define-constant +width+ 680)
(define-constant +height+ 460)

(define blue (list 0 0 1 1))

(new-doodle background: solid-white)

(define +pi+ 3.14159265358979323846)
(define (->radians x) (* x (/ +pi+ 180)))

(define mercator-x ->radians)
(define (mercator-y y)
  (let ((tany (tan (->radians y))))
    (log (+ tany (sqrt (+ (* tany tany) 1))))))

(define min-x (mercator-x (fold (lambda (c s) (min s (get-x (coord c)))) most-positive-fixnum cities)))
(define max-x (mercator-x (fold (lambda (c s) (max s (get-x (coord c)))) 0 cities)))

(define min-y (mercator-y (fold (lambda (c s) (min s (get-y  (coord c)))) most-positive-fixnum cities)))
(define max-y (mercator-y (fold (lambda (c s) (max s (get-y  (coord c)))) 0 cities)))

(define (scale val min max mapped-min mapped-max)
  (* (+ mapped-min (- mapped-max mapped-min))
     (/ (- val min)
        (- max min))))

(print "min-x: " min-x ", max-x: " max-x ", min-y: " min-y ", max-y: " max-y)

(for-each (lambda (c) (let* ((xy (coord c))
                             (x (get-x xy))
                             (y (get-y xy))
                             (scaled-x (scale (mercator-x x) min-x max-x +width+ +height+))
                             (scaled-y (scale (mercator-y y) min-y max-y +width+ +height+)))
                        (circle scaled-x (- +height+ scaled-y) 1 blue)))
          cities)

(show!)
(save-screenshot "germany.png")

slightly corrected version added by C-Keen on Thu Jan 26 16:24:19 2012

(use numbers doodle)

; get from http://pestilenz.org/~ckeen/staedte.sexpr
(define cities (with-input-from-file "staedte.sexpr" read))

(define coord second)
(define get-x first)
(define get-y second)

(define blue (list 0 0 1 1))

(define +pi+ 3.14159265358979323846)
(define (->radians x) (* x (/ +pi+ 180)))

(define mercator-x ->radians)
(define (mercator-y y)
  (let ((tany (tan (->radians y))))
    (log (+ tany (sqrt (+ (* tany tany) 1))))))

(define min-x (mercator-x (fold (lambda (c s) (min s (get-x (coord c)))) most-positive-fixnum cities)))
(define max-x (mercator-x (fold (lambda (c s) (max s (get-x (coord c)))) 0 cities)))

(define min-y (mercator-y (fold (lambda (c s) (min s (get-y  (coord c)))) most-positive-fixnum cities)))
(define max-y (mercator-y (fold (lambda (c s) (max s (get-y  (coord c)))) 0 cities)))

(define (scale val min max mapped-min mapped-max)
  (* (+ mapped-min (- mapped-max mapped-min))
     (/ (- val min)
        (- max min))))

(define aspect (/ (- max-x min-x) (- max-y min-y)))

(define-constant +width+ 1000)
(define-constant +height+ (inexact->exact (round (/ +width+ aspect))))
(define-constant +radius+ 1)

(new-doodle background: solid-white width: +width+ height: +height+)

(print "aspect: " aspect " radius: " +radius+ " min-x: " min-x ", max-x: " max-x ", min-y: " min-y ", max-y: " max-y)

(for-each (lambda (c) (let* ((xy (coord c))
                             (x (get-x xy))
                             (y (get-y xy))
                             (scaled-x (scale (mercator-x x) min-x max-x 0 +width+))
                             (scaled-y (scale (mercator-y y) min-y max-y 0 +height+)))
                        (circle scaled-x (- +height+ scaled-y) +radius+ blue)))
          cities)

(show!)
(save-screenshot "germany.png")
(exit 0)