route.ml 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. (*
  2. * Parse path and Query string
  3. *
  4. * We have either a
  5. *
  6. * path: /<geohash>/<format>
  7. * or
  8. * query_string: ?q=<lat><sep><lon>
  9. *)
  10. module P = struct
  11. open Tyre
  12. let ws = pcre "( |\t|\\+|%20)*"
  13. let deg_min_sec =
  14. conv
  15. (fun ((d, (m, s)), he) ->
  16. let si = match he with
  17. | "S" | "W" -> -1.
  18. | _ -> 1.
  19. and d' = d
  20. and m' = m
  21. and s' = s in
  22. si *. (d' +. ((m' +. (s' /. 60.)) /. 60.)))
  23. (fun v ->
  24. let si = if v < 0. then -1. else 1. in
  25. let d' = v *. si in
  26. let d = d' |> floor in
  27. let dr = d' -. d in
  28. let m' = dr *. 60. in
  29. let m = m' |> floor in
  30. let mr' = m' -. m in
  31. let se = mr' *. 60. in
  32. ((d, (m, se)), if si < 0. then "S" else "N"))
  33. (float <* pcre "°|%C2%B0" <* ws
  34. <&> (float <* pcre "'|′|%27|%E2%80%B2" <* ws
  35. <&> (float <* pcre "\"|″|%22|%E2%80%B3" <* ws))
  36. <&> pcre "[NSEOW]")
  37. let dec = float <* opt (str "%C2%B0")
  38. let deg =
  39. conv
  40. (fun x -> match x with
  41. | `Left v | `Right v -> v)
  42. (fun y -> (* write decimal by default *) `Left y)
  43. (dec <|> deg_min_sec)
  44. let sep = pcre "([,; +]|%20|%2C|%3B)+"
  45. let lat_lon_pair = deg <&> sep *> deg
  46. let geo_uri =
  47. opt (pcre "geo(:|%3A)") *> lat_lon_pair
  48. <* opt (pcre "(\\?|%3F)z(=|%3D)[0-9]+")
  49. let lat_lon = compile (geo_uri <* stop)
  50. let qs_lat_lon = compile (str "q=" *> geo_uri <* stop)
  51. end
  52. let coord_from_qs qs = qs |> Tyre.exec P.qs_lat_lon
  53. let coord_from_s s = s |> Tyre.exec P.lat_lon