001  (ns walkmap.microworld
002    "An interface between walkmap and microworld, to allow use of microworld
003    functionality to model things like rainfall, soil fertility, settlement
004    and so on."
005    (:require [clojure.edn :as edn :only [read]]
006              [clojure.java.io :as io]
007              [clojure.string :as s]
008              [taoensso.timbre :as l]
009              [walkmap.edge :as e]
010              [walkmap.polygon :as p :only [rectangle]]
011              [walkmap.superstructure :refer [store]]
012              [walkmap.tag :as t :only [tag]]
013              [walkmap.vertex :as v :only [check-vertex vertex vertex?]]
014              [walkmap.utils :as u :only [truncate]]))
015  
016  (defn cell->polygon
017    "From this MicroWorld `cell`, construct a walkmap polygon (specifically,
018    a rectangle. If `scale-vector` passed and is a vertex, scale all the vertices
019    in the cell by that vector."
020    ([cell]
021     (cell->polygon cell (v/vertex 1 1 1)))
022    ([cell scale-vector]
023     (t/tag
024       (assoc
025         (merge
026           cell
027           (let [w (* (:x cell) (:x (v/check-vertex scale-vector)))
028                 s (* (:y cell) (:y scale-vector))
029                 e (+ w (:x scale-vector))
030                 n (+ s (:y scale-vector))
031                 z (* (:altitude cell) (:z scale-vector))]
032           (p/rectangle
033             (v/vertex s w z)
034             (v/vertex n e z))))
035         :walkmap.id/id
036         (keyword (gensym "mw-cell")))
037       (:state cell))))
038  
039  (defn load-microworld-edn
040    "While it would be possible to call MicroWorld functions directly from
041    Walkmap, the fact is that running MicroWorld is so phenomenally
042    compute-heavy that it's much more sensible to do it in batch mode. So the
043    better plan is to be able to pull the output from MicroWorld - as an EDN
044    structure - into a walkmap superstructure."
045    ([filename]
046     (load-microworld-edn filename :mw))
047    ([filename map-kind]
048     (when-not
049       (keyword? map-kind)
050       (throw (IllegalArgumentException.
051                (u/truncate
052                  (str "Must be a keyword: " (or map-kind "nil")) 80))))
053     (load-microworld-edn filename map-kind nil))
054    ([filename mapkind superstucture]
055     (load-microworld-edn filename mapkind superstucture (v/vertex 1 1 1)))
056    ([filename map-kind superstructure scale-vertex]
057     (let [mw (try
058                (with-open [r (io/reader filename)]
059                  (edn/read (java.io.PushbackReader. r)))
060                (catch RuntimeException e
061                  (l/error "Error parsing edn file '%s': %s\n"
062                           filename (.getMessage e))))
063           polys (reduce
064                   concat
065                   (map (fn [row] (map cell->polygon row)) mw))]
066       (if (map? superstructure)
067         (reduce
068           #(store %2 %1)
069           superstructure
070           polys)
071         polys))))
072  
073  
074  
075