#6: Automatic pan and zoom on loading data now works

Additionally, all client namespaces have been renamed to geocsv.client.xxx to avoid confusion with server side namespaces.
This commit is contained in:
Simon Brooke 2020-01-29 19:05:34 +00:00
parent 4516980981
commit ce7b204a19
No known key found for this signature in database
GPG key ID: A7A4F18D1D4DF987
8 changed files with 66 additions and 28 deletions

View file

@ -1,6 +1,6 @@
(ns^:figwheel-no-load geocsv.app
(:require
[geocsv.core :as core]
[geocsv.client.core :as core]
[cljs.spec.alpha :as s]
[expound.alpha :as expound]
[devtools.core :as devtools]))

View file

@ -107,7 +107,7 @@
:cljsbuild{:builds
{:app
{:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
:figwheel {:on-jsload "geocsv.core/mount-components"}
:figwheel {:on-jsload "geocsv.client.core/mount-components"}
:compiler
{:output-dir "target/cljsbuild/public/js/out"
:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}

View file

@ -1,4 +1,4 @@
(ns geocsv.ajax
(ns geocsv.client.ajax
(:require
[ajax.core :as ajax]
[luminus-transit.time :as time]

View file

@ -1,15 +1,15 @@
(ns geocsv.core
(ns geocsv.client.core
(:require
[day8.re-frame.http-fx]
[reagent.core :as r]
[re-frame.core :as rf]
[geocsv.gis :as gis]
[geocsv.views.map :as mv]
[geocsv.client.gis :as gis]
[geocsv.client.views.map :as mv]
[goog.events :as events]
[goog.history.EventType :as HistoryEventType]
[markdown.core :refer [md->html]]
[geocsv.ajax :as ajax]
[geocsv.events]
[geocsv.client.ajax :as ajax]
[geocsv.client.events]
[reitit.core :as reitit]
[reitit.frontend.easy :as rfe]
[clojure.string :as s])

View file

@ -1,6 +1,6 @@
(ns ^{:doc "geocsv app initial database."
:author "Simon Brooke"}
geocsv.db)
geocsv.client.db)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -37,5 +37,7 @@
"Operator"
"Other-key-customers"
"Power-supplier"} ;; need to be fetched from server side
:latitude 56
:longitude -4
:map {:map-centre [56 -4]
:map-zoom 6}})

View file

@ -1,9 +1,9 @@
(ns geocsv.events
(ns geocsv.client.events
(:require [ajax.core :as ajax]
[ajax.json :refer [json-request-format json-response-format]]
[cemerick.url :refer [url url-encode]]
[geocsv.db :refer [default-db]]
[geocsv.gis :refer [refresh-map-pins]]
[geocsv.client.db :refer [default-db]]
[geocsv.client.gis :refer [compute-centre refresh-map-pins]]
[re-frame.core :as rf]
[reitit.frontend.easy :as rfe]
[reitit.frontend.controllers :as rfc]))
@ -40,7 +40,6 @@
:query nil
:anchor nil))
;;dispatchers: keep in alphabetical order, please.
(rf/reg-event-fx
:bad-data
@ -138,12 +137,15 @@
;; TODO: why is this an `-fx`? Does it need to be?
(fn
[{db :db} [_ response]]
(let [data (js->clj response)]
(let [db' (assoc db :data (js->clj response))]
(js/console.log (str "processing fetched JSON data"))
{:db (if
(:view db)
(refresh-map-pins (assoc db :data data))
db)})))
{:db (if-let [data (:data db')]
(let [centre (compute-centre data)]
(if
(:view db')
(refresh-map-pins (merge db' centre))
db)
db))})))
(rf/reg-event-fx
:process-pin-image-names

View file

@ -1,6 +1,6 @@
(ns ^{:doc "geocsv app map stuff."
:author "Simon Brooke"}
geocsv.gis
geocsv.client.gis
(:require [ajax.core :refer [GET]]
[ajax.json :refer [json-request-format json-response-format]]
[cljs.reader :refer [read-string]]
@ -158,17 +158,52 @@
(.removeLayer view %)))
view))
(defn compute-zoom
"See [explanation here](https://leafletjs.com/examples/zoom-levels/). Brief
summary: it's hard, but it doesn't need to be precise."
[min-lat max-lat min-lng max-lng]
(let [n (min (/ 360 (- max-lng min-lng)) (/ 180 (- max-lat min-lat)))]
(first
(remove
nil?
(map
#(if (> (reduce * (repeat 2 %)) n) %)
(range))))))
(defn compute-centre
"Compute, and return as a map with keys `:latitude` and `:longitude`, the
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))
min-lat (apply min lats)
max-lat (apply max lats)
lngs (filter number? (map :longitude records))
min-lng (apply min lngs)
max-lng (apply max lngs)]
(if-not
(or (empty? lats) (empty? lngs))
{:latitude (+ min-lat (/ (- max-lat min-lat) 2))
:longitude (+ min-lng (/ (- max-lng min-lng) 2))
:zoom (compute-zoom min-lat max-lat min-lng max-lng)}
{})))
(defn refresh-map-pins
"Refresh the map pins on the current map. Side-effecty; liable to be
problematic."
[db]
(let [view (map-remove-pins @(subscribe [:view]))
data (:data db)]
data (:data db)
centre (compute-centre data)]
(if
view
(let [added (remove nil? (map #(add-map-pin db %1 %2 view) data (range)))]
(js/console.log (str "Adding " (count added) " pins"))
db)
(if
(:latitude centre)
(do
(js/console.log (str "computed centre: " centre))
(.setView view (clj->js [(:latitude centre) (:longitude centre)]) (:zoom centre))
(merge db centre))
db))
(do (js/console.log "View is not yet ready") db))))

View file

@ -1,11 +1,11 @@
(ns ^{:doc "a map onto which to project CSV data."
:author "Simon Brooke"}
geocsv.views.map
geocsv.client.views.map
(:require [cljsjs.leaflet]
[re-frame.core :refer [reg-sub subscribe dispatch dispatch-sync]]
[reagent.core :as reagent]
[recalcitrant.core :refer [error-boundary]]
[geocsv.gis :refer [refresh-map-pins get-current-location]]))
[geocsv.client.gis :refer [refresh-map-pins get-current-location]]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;
@ -61,9 +61,8 @@
(let [view (.setView
(.map js/L
"map"
;; (clj->js {:zoomControl false})
)
#js [56 -4] ;;[@(subscribe [:latitude]) @(subscribe [:longitude])]
(clj->js {:zoomControl false}))
#js [@(subscribe [:latitude]) @(subscribe [:longitude])]
@(subscribe [:zoom]))]
(.addTo (.tileLayer js/L osm-url
(clj->js {:attribution osm-attrib