about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2023-10-14 21:13:25 +0100
committerArun Isaac2023-10-14 21:33:57 +0100
commitc26df4b22651fa3077ef2c2a1643e810b2864ece (patch)
treebf88f12c742ac67828d35be5daa0cffbe5176abf
parent156dd142883f924cdce11e9ddd41dc11ed604294 (diff)
downloadrent-in-london-c26df4b22651fa3077ef2c2a1643e810b2864ece.tar.gz
rent-in-london-c26df4b22651fa3077ef2c2a1643e810b2864ece.tar.lz
rent-in-london-c26df4b22651fa3077ef2c2a1643e810b2864ece.zip
Query OSRM API for multiple destinations at once.
Batching OSRM queries so that distances to multiple points are queried
at once is more efficient.

* rent.scm (cycling-distance): Delete function.
(cycling-distances): New function.
(%wembley-stadium): New variable.
(list-house): Use cycling-distances with multiple destinations.
-rw-r--r--rent.scm85
1 files changed, 49 insertions, 36 deletions
diff --git a/rent.scm b/rent.scm
index d380d1f..062795b 100644
--- a/rent.scm
+++ b/rent.scm
@@ -45,6 +45,10 @@
 (define %work-coordinates
   #(51.52305 -0.13295))
 
+;; Another frequent destination, say Wembley stadium
+(define %wembley-stadium
+  #(51.55537 -0.28636))
+
 (define %openrent-base-url
   "https://www.openrent.co.uk")
 
@@ -343,27 +347,32 @@ characters. Else, return @code{#f}."
                      '())))
      (*default* . ,handle-default))))
 
-(define (cycling-distance point-a point-b)
-  "Compute the cycling distance between @var{point-a} and
-@var{point-b}. The returned distance is the actual distance by cycle,
-and not distance as the crow flies."
-  (match (list point-a point-b)
-    ((#(point-a-latitude point-a-longitude)
-      #(point-b-latitude point-b-longitude))
-     (call-with-port (open-bytevector-input-port
-                      (http-get*
-                       ;; We use ~f for latitude/longitude since ~a
-                       ;; would use the exponential float notation for
-                       ;; small numbers and the API does not like
-                       ;; that.
-                       (format #f "~a/table/v1/bike/~f,~f;~f,~f?annotations=distance&sources=0&destinations=1"
-                               %osrm-base-url
-                               point-a-longitude point-a-latitude
-                               point-b-longitude point-b-latitude)))
-       (lambda (port)
-         (/ (json-ref (json->scm port)
-                      "distances" 0 0)
-            1000))))))
+(define (cycling-distances source . destinations)
+  "Compute the cycling distance between @var{source}, a point, and
+@var{destinations}, a list of points. The returned distance is a list
+of actual distances by cycle, and not distance as the crow flies."
+  (call-with-port (open-bytevector-input-port
+                   (http-get*
+                    ;; We use ~f for latitude/longitude since ~a
+                    ;; would use the exponential float notation for
+                    ;; small numbers and the API does not like
+                    ;; that.
+                    (format #f "~a/table/v1/bike/~a?annotations=distance&sources=0&destinations=~a"
+                            %osrm-base-url
+                            (string-join
+                             (map (match-lambda
+                                    (#(latitude longitude)
+                                     (format #f "~f,~f" longitude latitude)))
+                                  (cons source destinations))
+                             ";")
+                            (string-join
+                             (map number->string
+                                  (iota (length destinations) 1))
+                             ";"))))
+    (lambda (port)
+      (map (cut / <> 1000)
+           (vector->list (json-ref (json->scm port)
+                                   "distances" 0))))))
 
 (define (lines-at-station station-name)
   "Return a list of tube lines serving @var{station-name}."
@@ -397,25 +406,29 @@ and not distance as the crow flies."
 
 (define (list-house house)
   "Display details of @var{house} on the current output port."
-  (format (current-output-port)
-          "~a (posted ~a ago)
+  (apply format
+         (current-output-port)
+         "~a (posted ~a ago)
 ~a/~a
 £~a pcm
 Available from ~a
-Cycling distance: ~,1f km
+Cycling distance to work: ~,1f km
+Cycling distance to Wembley stadium: ~,1f km
 "
-          (house-title house)
-          (if (< (house-hours-live house) 24)
-              (format #f "~a hours"
-                      (house-hours-live house))
-              (format #f "~a days"
-                      (round-quotient (house-hours-live house)
-                                      24)))
-          %openrent-base-url
-          (house-property-id house)
-          (house-rent house)
-          (date->string (house-available-from house) "~B ~d")
-          (cycling-distance (house-coordinates house) %work-coordinates))
+         (house-title house)
+         (if (< (house-hours-live house) 24)
+             (format #f "~a hours"
+                     (house-hours-live house))
+             (format #f "~a days"
+                     (round-quotient (house-hours-live house)
+                                     24)))
+         %openrent-base-url
+         (house-property-id house)
+         (house-rent house)
+         (date->string (house-available-from house) "~B ~d")
+         (cycling-distances (house-coordinates house)
+                            %work-coordinates
+                            %wembley-stadium))
   (match (house-tube-stations house)
     (() (display "No tube!"))
     (tube-stations