OK, this is fucking impressive if I say so myself.

This commit is contained in:
Simon Brooke 2020-02-22 12:43:29 +00:00
parent 64fd9ffb5b
commit d001338a49
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
8 changed files with 154 additions and 57 deletions

View file

@ -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))))
)

View file

@ -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))))

View file

@ -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)))]

View file

@ -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))