Last active
April 5, 2020 10:54
-
-
Save jl2/fd324fa3faa919803152465fade14b6b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ql:quickload :cl-csv) | |
(ql:quickload :zip) | |
(ql:quickload :cl-strings) | |
;; Download transit data from this French site: | |
;; https://www.data.gouv.fr/fr/datasets/transport-donnees-gtfs/ | |
(defun read-transit-data (&key (zip-file-path "~/Downloads/gtfs_current.zip")) | |
(flet ((csv-name-to-lisp (name) | |
(string-upcase (cl-strings:replace-all name "_" "-")))) | |
(zip:with-zipfile (zf zip-file-path) | |
(loop | |
with entries = (zip:zipfile-entries zf) | |
for name being the hash-keys of entries | |
using (hash-value entry) | |
collect | |
(let* ((cls-name (csv-name-to-lisp (pathname-name name))) | |
(cls-sym (intern cls-name)) | |
(keyword-name (intern cls-name "KEYWORD")) | |
(data (cl-csv:read-csv | |
(flexi-streams:octets-to-string | |
(zip:zipfile-entry-contents entry)))) | |
(keyws (loop | |
for slot-name in (car data) | |
for sname = (csv-name-to-lisp slot-name) | |
for sym = (intern sname) | |
for keyword = (intern sname "KEYWORD") | |
collect (list sym :initarg keyword) into members | |
collect keyword into keywords | |
collect sym into symbols | |
finally (return | |
(progn | |
(eval `(defclass ,cls-sym () | |
( ,@members ))) | |
(eval `(defmethod print-object ((object ,cls-sym) stream) | |
(with-slots ,symbols object | |
(format stream "(~a ~{ ~s~^ ~})" | |
(quote ,cls-sym) | |
(list ,@symbols))))) | |
keywords))))) | |
(cons keyword-name | |
(loop | |
for row-values in (cdr data) | |
collect (apply #'make-instance cls-sym (loop | |
for keyw in keyws | |
for val in row-values | |
collect keyw collect val))))))))) | |
(defun select (data slot value) | |
(loop for object in data | |
when (string= value (slot-value object slot)) | |
collect object)) | |
(defun table (transit-data type) | |
(assoc-value transit-data type)) | |
;; Read CSV data from Zip file | |
(defparameter *transit-data* (read-transit-data)) | |
;; Query something | |
(select | |
(select (table *transit-data* :trips) 'trip-headsign "L5a - MAISON NEUVE") | |
'route-id "5-77") | |
(select (table *transit-data* :trips) 'route-id "5-77") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment