Skip to content
Snippets Groups Projects
Commit a182505f authored by Allen Gilliland's avatar Allen Gilliland
Browse files

do some final cleanup and bug fixing and implement the final bit that takes...

do some final cleanup and bug fixing and implement the final bit that takes the results of our dataset query, extracts the lat/lon points, and feeds them into our PinMap overlay java class for rendering.  everything should be working end to end now.
parent 97637f5a
Branches
Tags
No related merge requests found
......@@ -12,10 +12,10 @@
(def pixel-per-lon-degree (float (/ tile-size 360.0)))
(def pixel-per-lon-radian (float (/ tile-size (* 2 (java.lang.Math/PI)))))
(defn radians-to-degrees [rad]
(defn- radians-to-degrees [rad]
(float (/ rad (float (/ (java.lang.Math/PI) 180)))))
(defn tile-lat-lon
(defn- tile-lat-lon
"Get the Latitude & Longitude of the upper left corner of a given tile"
[x y zoom]
(let [num-tiles (bit-shift-left 1 zoom)
......@@ -24,12 +24,12 @@
lon (float (/ (- corner-x pixel-origin) pixel-per-lon-degree))
lat-radians (/ (- corner-y pixel-origin) (* pixel-per-lon-radian -1))
lat (radians-to-degrees (- (* 2 (java.lang.Math/atan (java.lang.Math/exp lat-radians)))
(/ 2 (java.lang.Math/PI))))]
(/ (java.lang.Math/PI) 2)))]
{:lat lat
:lon lon}))
(defn query-with-inside-filter
(defn- query-with-inside-filter
"Add an 'Inside' filter to the given query to restrict results to a bounding box"
[details lat-field-id lon-field-id x y zoom]
(let [{top-lt-lat :lat top-lt-lon :lon} (tile-lat-lon x y zoom)
......@@ -47,6 +47,24 @@
(assoc details :filter (conj ["AND"] (:filter details) inside-filter))))))
(defn- extract-points
"Takes in a dataset query result object and pulls out the Latitude/Longitude pairs into nested `java.util.ArrayLists`.
This is specific to the way we plan to feed data into `com.metabase.corvus.api.tiles.GoogleMapPinsOverlay`."
[{{:keys [rows cols]} :data}]
(if-not (> (count rows) 0)
;; if we have no rows then return an empty list of points
(java.util.ArrayList. [])
;; otherwise we go over the data, pull out the lat/lon columns, and convert them to ArrayLists
(let [find-col-idx (fn [special-type]
(->> (map-indexed (fn [idx itm] (when (= special-type (:special_type itm)) idx)) cols)
(filter identity)
(first)))
lat-col-idx (find-col-idx "latitude")
lon-col-idx (find-col-idx "longitude")]
(->> (map (fn [row] (java.util.ArrayList. [(nth row lat-col-idx) (nth row lon-col-idx)])) rows)
(java.util.ArrayList.)))))
;; This endpoints provides an image with the appropriate pins rendered given a json query
;; We evaluate the query and find the set of lat/lon pairs which are relevant and then render the appropriate ones
;; It's expected that to render a full map view several calls will be made to this endpoint in parallel
......@@ -59,22 +77,19 @@
lon-field String->Integer
lat-col-idx String->Integer
lon-col-idx String->Integer}
;; TODO - tried to use `query String-Dict` above, but got errors with json parsing for some reason
(let [testpts (java.util.ArrayList. [(java.util.ArrayList. [37.7785264 -122.3943527])
(java.util.ArrayList. [37.7853604 -122.4329151])
(java.util.ArrayList. [37.8001008 -122.4420084])
(java.util.ArrayList. [37.757088 -122.4209783])
(java.util.ArrayList. [37.7962227 -122.4115758])])
query-dict (clojure.walk/keywordize-keys (json/read-str (get-in request [:params :query])))
points-inside-box-query-details (query-with-inside-filter (:query query-dict) lat-field lon-field x y zoom)
points (driver/dataset-query points-inside-box-query-details {:executed_by *current-user-id*
:synchronously true})]
;; TODO - tried to use `query String->Dict` above, but got errors with json parsing for some reason
(let [query-dict (clojure.walk/keywordize-keys (json/read-str (get-in request [:params :query])))
updated-query (assoc query-dict
:query (query-with-inside-filter (:query query-dict) lat-field lon-field x y zoom))
result (driver/dataset-query updated-query {:executed_by *current-user-id*
:synchronously true})
lat-lon-points (extract-points result)]
;; manual ring response here. we simply create an inputstream from the byte[] of our image
{:status 200
:headers {"Content-Type" "image/png"}
:body (java.io.ByteArrayInputStream.
(.toByteArray
(com.metabase.corvus.api.tiles.GoogleMapPinsOverlay. zoom testpts)))}))
(com.metabase.corvus.api.tiles.GoogleMapPinsOverlay. zoom lat-lon-points)))}))
(define-routes)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment