# walkmap/microworld.clj

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