OK, this is fucking impressive if I say so myself.
This commit is contained in:
parent
64fd9ffb5b
commit
d001338a49
8 changed files with 154 additions and 57 deletions
|
|
@ -6,14 +6,16 @@
|
|||
[geocsv-lite.gis :as gis]
|
||||
[geocsv-lite.map :as m]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
||||
(println "This text is printed from src/geocsv-lite/core.cljs. Go ahead and edit it and see reloading in action.")
|
||||
|
||||
|
||||
|
||||
|
||||
;; define your app data so that it doesn't get over-written on reload
|
||||
(defn ^:export initialise-map-element
|
||||
"Create a map view in the element with this `id` and decorate it with
|
||||
pins showing locations from this `data-source`."
|
||||
[id data-source]
|
||||
(js/console.log (str "geocsv-lite.core.initialise-map-element called with args id: " id "; data-source: " data-source "."))
|
||||
(let [sid (str id)
|
||||
kid (keyword sid)
|
||||
v (m/add-view sid 55 -4 10)]
|
||||
(.whenReady v (fn [] (get-data kid data-source)))))
|
||||
|
||||
(defonce app-state (atom {:text "Hello world!"}))
|
||||
|
||||
|
|
@ -21,11 +23,4 @@
|
|||
;; optionally touch your app-state to force rerendering depending on
|
||||
;; your application
|
||||
;; (swap! app-state update-in [:__figwheel_counter] inc)
|
||||
(m/add-view "map" 55 -4 10)
|
||||
(let [query (get-query-part-as-map)
|
||||
uri (get-csv-url query)
|
||||
records (get-data :map)]
|
||||
(dom/set-text (.getElementById js/document "message")
|
||||
(str "Query was: " query "; uri was: " uri))))
|
||||
|
||||
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,20 +8,12 @@
|
|||
[geocsv-lite.map :refer [get-view]]
|
||||
))
|
||||
|
||||
;; function getQueryVariable(variable)
|
||||
;; {
|
||||
;; var query = window.location.search.substring(1);
|
||||
;; var vars = query.split("&");
|
||||
;; for (var i=0;i<vars.length;i++) {
|
||||
;; var pair = vars[i].split("=");
|
||||
;; if(pair[0] == variable){return pair[1];}
|
||||
;; }
|
||||
;; return(false);
|
||||
;; }
|
||||
|
||||
|
||||
|
||||
(defn get-query-part-as-map
|
||||
"Returns the query part of the current document URL as a keyword-string map."
|
||||
;; not actually used in the current incarnation
|
||||
[]
|
||||
(let [query-nvs (map #(cs/split % "=") (cs/split (subs js/window.location.search 1) "&"))]
|
||||
(when (every? #(= (count %) 2) query-nvs)
|
||||
|
|
@ -35,6 +27,7 @@
|
|||
* `:uri` whose value is the URI of a JSON or CSV file.
|
||||
|
||||
If either of these keys is found, returns an appropriate URL, else nil."
|
||||
;; not actually used in the current incarnation
|
||||
[query]
|
||||
(when (map? query)
|
||||
(cond
|
||||
|
|
@ -46,35 +39,50 @@
|
|||
|
||||
|
||||
(defn default-handler
|
||||
"When data is received from a URL, it is received asynchronously. This
|
||||
is the default callback called with the `response` of the HTTP request,
|
||||
and the keyword `k` identifying the map view, to populate the map with
|
||||
data."
|
||||
[response k]
|
||||
(if
|
||||
(= (:status response) 200)
|
||||
(let [content (:body response)
|
||||
data (js->clj (.-data (.parse js/Papa content)))
|
||||
data (map
|
||||
#(merge %
|
||||
{:longitude (js/Number (:longitude %))
|
||||
:latitide (js/Number (:latitude %))})
|
||||
(js->clj (.-data (.parse js/Papa content (clj->js {:dynamicTyping true})))))
|
||||
cols (map
|
||||
#(let [n (cs/lower-case (cs/replace (cs/trim %) #"[^\w\d]+" "-"))]
|
||||
(keyword
|
||||
(if (empty? n)
|
||||
(gensym)
|
||||
n)))
|
||||
(first data))
|
||||
#(let [n (when-not
|
||||
(empty? %)
|
||||
(when (string? %)
|
||||
(cs/lower-case
|
||||
(cs/replace
|
||||
% #"[^\w\d]+" "-"))))]
|
||||
(keyword
|
||||
(if (empty? n)
|
||||
(gensym)
|
||||
n)))
|
||||
(first data))
|
||||
records (map
|
||||
(fn [r] (zipmap cols (map str r)))
|
||||
(rest data))
|
||||
]
|
||||
;; (println records)
|
||||
(gis/refresh-map-pins (get-view k) records))
|
||||
(println (str "Bad response from server: " (:status response)))))
|
||||
(js/console.error (str "Bad response from server: " (:status response)))))
|
||||
|
||||
|
||||
(defn get-data
|
||||
[k]
|
||||
"Get data for the view identified by this keyword `k` from this `data-source`.
|
||||
In this initial release the data source must be a URL, but in future releases
|
||||
I intend that it may also be a list of maps representing records, or a CSV or
|
||||
JSON formatted string."
|
||||
[k data-source]
|
||||
(let
|
||||
[uri (get-csv-url (get-query-part-as-map))]
|
||||
[uri data-source]
|
||||
(go (let [response (<! (http/get uri {:with-credentials? "false"
|
||||
:access-control-allow-credentials "true"
|
||||
:origin js/window.location.hostname}))]
|
||||
(println (cs/join " " ["tx:" uri "rx:" (:status response)]))
|
||||
(default-handler response k)))))
|
||||
|
||||
(defn get-data-with-uri-and-handler
|
||||
|
|
@ -83,7 +91,7 @@
|
|||
(apply handler-fn (list response k)))))
|
||||
|
||||
|
||||
(go (let [uri "http://localhost:3449/data/data.csv"
|
||||
response (<! (http/get uri))]
|
||||
(when (= (:status response) 200)
|
||||
(default-handler response :map))))
|
||||
;; (go (let [uri "http://localhost:3449/data/data.csv"
|
||||
;; response (<! (http/get uri))]
|
||||
;; (when (= (:status response) 200)
|
||||
;; (default-handler response :map))))
|
||||
|
|
|
|||
|
|
@ -116,8 +116,8 @@
|
|||
"Add an appropriate map-pin for this `record` in this map `view`, if it
|
||||
has a valid `:latitude` and `:longitude`."
|
||||
[record index view]
|
||||
(let [lat (:latitude record)
|
||||
lng (:longitude record)]
|
||||
(let [lat (js/Number (:latitude record))
|
||||
lng (js/Number (:longitude record))]
|
||||
(if
|
||||
(and
|
||||
(number? lat)
|
||||
|
|
@ -170,10 +170,10 @@
|
|||
centre of the locations of these records as indicated by the values of their
|
||||
`:latitude` and `:longitude` keys."
|
||||
[records]
|
||||
(let [lats (filter number? (map :latitude records))
|
||||
(let [lats (map js/Number (map :latitude records))
|
||||
min-lat (apply min lats)
|
||||
max-lat (apply max lats)
|
||||
lngs (filter number? (map :longitude records))
|
||||
lngs (filter js/Number (map :longitude records))
|
||||
min-lng (apply min lngs)
|
||||
max-lng (apply max lngs)]
|
||||
(if-not
|
||||
|
|
@ -185,11 +185,12 @@
|
|||
|
||||
(defn refresh-map-pins
|
||||
"Refresh the map pins on the current map. Side-effecty; liable to be
|
||||
problematic."
|
||||
problematic."
|
||||
[view records]
|
||||
(js/console.log "refresh-map-pins called")
|
||||
(let [view (map-remove-pins view)
|
||||
centre (compute-centre records)]
|
||||
(js/console.log (str "refresh-map-pins called; " (count records) " records, centre at " centre))
|
||||
(js/console.log (str "Type of longitude " (:longitude (first records)) " is: " (type (:longitude (first records)))))
|
||||
(if
|
||||
view
|
||||
(let [added (remove nil? (map #(add-map-pin %1 %2 view) records (range)))]
|
||||
|
|
|
|||
|
|
@ -72,16 +72,20 @@
|
|||
|
||||
(defn add-view
|
||||
[id lat lng zoom]
|
||||
(let [k (keyword id)]
|
||||
(when-not
|
||||
(@views k)
|
||||
(swap! views assoc k (map-did-mount id lat lng zoom)))
|
||||
(views k)))
|
||||
(let [k (keyword id)
|
||||
v (or
|
||||
(@views k)
|
||||
(map-did-mount id lat lng zoom))]
|
||||
(js/console.log (str "Added Leaflet view to element with id `" id "`"))
|
||||
(swap! views assoc k v)
|
||||
v))
|
||||
|
||||
|
||||
(defn get-view
|
||||
[k]
|
||||
(@views k))
|
||||
(when-not (keyword? k) (js/console.log "Key `" k "` passed to get-view is not a keyword"))
|
||||
(when-not (k @views) (js/console.log "Key `" k "` does not identify a known view"))
|
||||
(k @views))
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue