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