Compare commits
44 commits
8e88bbaf67
...
db37034a70
| Author | SHA1 | Date | |
|---|---|---|---|
| db37034a70 | |||
| e16618f49e | |||
| 25be80020b | |||
| 0756aef64b | |||
| 7ab765a333 | |||
| 107c27db95 | |||
| 00dc9e6851 | |||
| ca369c219e | |||
| 8ade976f6c | |||
| ce61a7a77a | |||
| 7fd1ca44e4 | |||
| f0a168c8e9 | |||
| a44f13085d | |||
| 16e5fe0b2e | |||
| 3d19bc3f40 | |||
| 076e3dd279 | |||
| 71cdf5f97c | |||
| bbe481c064 | |||
| b2c78c1e5d | |||
| a8266ae615 | |||
| 1118889253 | |||
| b9c6864ef1 | |||
| 1e581ef172 | |||
| fd38f85f72 | |||
| 0c36e1336d | |||
| ce8dcba87a | |||
| 7effdcc577 | |||
| 23ea827e40 | |||
| 2affa8b5fa | |||
| ede9b2076d | |||
| a438e54f42 | |||
| fbcb87f0d8 | |||
| c3766414c3 | |||
| 5fecae013c | |||
| 10aaf21209 | |||
| 83527f5cae | |||
| 06c614d2c5 | |||
| 38c0d5ef53 | |||
| 68ee03bead | |||
| 0370fb97a2 | |||
| f0435c549b | |||
| d6195f00e9 | |||
| dbfbaeda60 | |||
| 2a760bc98d |
48 changed files with 1767 additions and 358 deletions
|
|
@ -1,4 +1,4 @@
|
|||
version=0.21.0
|
||||
version=0.28.1
|
||||
assignment-operator=end-line
|
||||
break-cases=fit
|
||||
break-fun-decl=wrap
|
||||
|
|
|
|||
12
CHANGES.md
12
CHANGES.md
|
|
@ -1 +1,11 @@
|
|||
## unreleased
|
||||
## 0.2
|
||||
|
||||
- use leaflet.js v1.9.4
|
||||
- some small breaking changes
|
||||
- add more bindings
|
||||
- use dune-site to "install" css and images files
|
||||
- provide example
|
||||
|
||||
## 0.1
|
||||
|
||||
Initial release.
|
||||
|
|
|
|||
11
LICENSE.md
11
LICENSE.md
|
|
@ -1,8 +1,9 @@
|
|||
The ISC License (ISC)
|
||||
=====================
|
||||
Copyright 2022 pukkamustard <pukkamustard@posteo.net>, swrup <swrup@protonmail.com>, pena <pena@kumikode.org>
|
||||
|
||||
Copyright © 2022, TODO
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
|||
28
README.md
28
README.md
|
|
@ -1,6 +1,6 @@
|
|||
# leaflet
|
||||
|
||||
[leaflet] is an [OCaml] executable/library to TODO.
|
||||
`leaflet` is an [OCaml] bindings library for the [Leaflet] JavaScript library (v1.9.4).
|
||||
|
||||
## Installation
|
||||
|
||||
|
|
@ -14,27 +14,33 @@ If you don't have `opam`, you can install it following the [how to install opam]
|
|||
|
||||
If you can't or don't want to use `opam`, consult the [opam file] for build instructions.
|
||||
|
||||
## Quickstart
|
||||
## Usage
|
||||
|
||||
```ocaml
|
||||
let () = Format.printf "TODO@."
|
||||
The library use `dune-site` to install [leaflet's files] (CSS and images).
|
||||
|
||||
Have a look at the [example] folder.
|
||||
It use [tiny_httpd] to provide a simple web page with a map that use [OpenStreetMap] tiles:
|
||||
```sh
|
||||
dune build @install
|
||||
dune exec example/server.exe
|
||||
```
|
||||
|
||||
For more, have a look at the [example] folder, at the [documentation] or at the [test suite].
|
||||
|
||||
## About
|
||||
|
||||
This library started off from the code of a [NGI0 funded project]
|
||||
|
||||
- [LICENSE]
|
||||
- [CHANGELOG]
|
||||
|
||||
[CHANGELOG]: ./CHANGES.md
|
||||
[example]: ./example
|
||||
[LICENSE]: ./LICENSE.md
|
||||
[opam file]: ./leaflet.opam
|
||||
[test suite]: ./test
|
||||
|
||||
[documentation]: TODO/leaflet
|
||||
[how to install opam]: https://opam.ocaml.org/doc/Install.html
|
||||
[OCaml]: https://ocaml.org
|
||||
[opam]: https://opam.ocaml.org/
|
||||
[leaflet]: TODO/leaflet
|
||||
[Leaflet]: https://leafletjs.com/
|
||||
[Leaflet's files]: ./src/vendor/
|
||||
[NGI0 funded project]: https://nlnet.nl/project/openEngiadina/
|
||||
[tiny_httpd]: https://github.com/c-cube/tiny_httpd
|
||||
[example]: ./example/
|
||||
[OpenStreetMap]: https://www.openstreetmap.org
|
||||
|
|
|
|||
|
|
@ -1,17 +1,7 @@
|
|||
{0 leaflet}
|
||||
{0 Leaflet}
|
||||
|
||||
{{:https://TODO/leaflet} leaflet} is an {{:https://ocaml.org} OCaml} library/executable to TODO.
|
||||
|
||||
{1:api API}
|
||||
Leaflet is an [OCaml] bindings library for the {{:https://leafletjs.com} Leaflet} JavaScript library.
|
||||
|
||||
{!modules:
|
||||
Leaflet
|
||||
}
|
||||
|
||||
{1:private_api Private API}
|
||||
|
||||
You shouldn't have to use any of these modules, they're used internally only.
|
||||
|
||||
{!modules:
|
||||
TODO
|
||||
}
|
||||
|
|
|
|||
35
dune-project
35
dune-project
|
|
@ -1,33 +1,20 @@
|
|||
(lang dune 2.9)
|
||||
|
||||
(implicit_transitive_deps false)
|
||||
(using dune_site 0.1)
|
||||
;uncomment when fixed: https://github.com/ocaml/dune/issues/9661
|
||||
;(implicit_transitive_deps false)
|
||||
|
||||
(name leaflet)
|
||||
|
||||
(license ISC)
|
||||
|
||||
(authors "TODO")
|
||||
|
||||
(maintainers "TODO")
|
||||
|
||||
(source
|
||||
(uri TODO/leaflet))
|
||||
|
||||
(homepage TODO/leaflet)
|
||||
|
||||
(bug_reports TODO/leaflet)
|
||||
|
||||
(documentation TODO/leaflet)
|
||||
|
||||
(generate_opam_files true)
|
||||
(generate_opam_files false)
|
||||
|
||||
(package
|
||||
(name leaflet)
|
||||
(synopsis "OCaml library/executable to TODO")
|
||||
(description
|
||||
"leaflet is an OCaml library/executable to TODO.")
|
||||
(tags
|
||||
(leaflet TODO TODO TODO TODO))
|
||||
(depends
|
||||
(ocaml
|
||||
(>= 4.08))))
|
||||
(>= 4.08))
|
||||
brr
|
||||
js_of_ocaml
|
||||
dune-site
|
||||
(tiny_httpd :with-test)
|
||||
)
|
||||
(sites (share css) (share images)))
|
||||
|
|
|
|||
0
example/css_path.ml
Normal file
0
example/css_path.ml
Normal file
26
example/dune
26
example/dune
|
|
@ -1,3 +1,25 @@
|
|||
(executable
|
||||
(name main)
|
||||
(modules main))
|
||||
(name script)
|
||||
(modules script)
|
||||
(libraries brr leaflet)
|
||||
(modes js))
|
||||
|
||||
(executable
|
||||
(name server)
|
||||
(modules content server css_path mysites)
|
||||
(libraries dune-site tiny_httpd))
|
||||
|
||||
(generate_sites_module
|
||||
(module mysites)
|
||||
(sites leaflet))
|
||||
|
||||
(rule
|
||||
(with-stdout-to
|
||||
content.ml
|
||||
(progn
|
||||
(echo "let index_html = {|")
|
||||
(cat index.html)
|
||||
(echo "|}")
|
||||
(echo "let script_js = {|")
|
||||
(cat script.bc.js)
|
||||
(echo "|}"))))
|
||||
|
|
|
|||
15
example/index.html
Normal file
15
example/index.html
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- dune-site should have installed leaflet.css
|
||||
you can use css_path.ml to get it's path -->
|
||||
<link href="leaflet.css" rel="stylesheet">
|
||||
<script type="text/javascript" src="script.js" defer="defer"></script>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<!-- don't forget to set a size! -->
|
||||
<div id="map" style="height: 700px; width: 700px"></div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1 +0,0 @@
|
|||
let () = Format.printf "TODO@."
|
||||
16
example/script.ml
Normal file
16
example/script.ml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
(* this file will be compiled to js
|
||||
you can then open map.html to see a simple page with a map loaded
|
||||
by this script *)
|
||||
|
||||
(* create map *)
|
||||
let map = Leaflet.Map.create_on "map"
|
||||
|
||||
(* setup map *)
|
||||
let () =
|
||||
(* set osm layer *)
|
||||
let osm_layer = Leaflet.Layer.create_tile_osm [||] in
|
||||
Leaflet.Layer.add_to map osm_layer;
|
||||
|
||||
(* set view *)
|
||||
let latlng = Leaflet.Latlng.create ~lat:40.71 ~lng:(-74.0) in
|
||||
ignore @@ Leaflet.Map.set_view latlng ~zoom:(Some 13) map
|
||||
44
example/server.ml
Normal file
44
example/server.ml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
let read_file file = In_channel.with_open_bin file In_channel.input_all
|
||||
|
||||
let leaflet_css =
|
||||
(* get leaflet.css path from dune-site *)
|
||||
let dune_site = List.filter Sys.file_exists Mysites.Sites.css in
|
||||
let lookup_file filename =
|
||||
List.find_map
|
||||
(fun dir ->
|
||||
let filename' = Filename.concat dir filename in
|
||||
if Sys.file_exists filename' then Some filename' else None )
|
||||
dune_site
|
||||
in
|
||||
let path =
|
||||
match lookup_file "leaflet.css" with
|
||||
| None ->
|
||||
Printf.eprintf
|
||||
"File 'leaflet.css' not found.\n\
|
||||
It should have been installed with dune-site.\n\
|
||||
Did you run `dune build @install`?\n";
|
||||
exit 1
|
||||
| Some o -> o
|
||||
in
|
||||
read_file path
|
||||
|
||||
let script_js = Content.script_js
|
||||
|
||||
let index_html = Content.index_html
|
||||
|
||||
module S = Tiny_httpd
|
||||
|
||||
let () =
|
||||
let server = S.create () in
|
||||
S.add_route_handler server
|
||||
S.Route.(exact "leaflet.css" @/ return)
|
||||
(fun _req -> S.Response.make_string (Ok leaflet_css));
|
||||
S.add_route_handler server
|
||||
S.Route.(exact "script.js" @/ return)
|
||||
(fun _req -> S.Response.make_string (Ok script_js));
|
||||
S.add_route_handler server
|
||||
S.Route.(return)
|
||||
(fun _req -> S.Response.make_string (Ok index_html));
|
||||
|
||||
Printf.printf "listening on http://%s:%d/\n%!" (S.addr server) (S.port server);
|
||||
match S.run server with Ok () -> () | Error e -> raise e
|
||||
31
leaflet.opam
31
leaflet.opam
|
|
@ -1,17 +1,26 @@
|
|||
# This file is generated by dune, edit dune-project instead
|
||||
opam-version: "2.0"
|
||||
synopsis: "OCaml library/executable to TODO"
|
||||
description: "leaflet is an OCaml library/executable to TODO."
|
||||
maintainer: ["TODO"]
|
||||
authors: ["TODO"]
|
||||
license: "ISC"
|
||||
tags: ["leaflet" "TODO" "TODO" "TODO" "TODO"]
|
||||
homepage: "TODO/leaflet"
|
||||
doc: "TODO/leaflet"
|
||||
bug-reports: "TODO/leaflet"
|
||||
name: "leaflet"
|
||||
version: "0.2"
|
||||
synopsis: "Bindings for the Leaflet JavaScript library"
|
||||
description:
|
||||
"leaflet is an OCaml bindings library for the Leaflet JavaScript library."
|
||||
maintainer: ["swrup <swrup@protonmail.com>"]
|
||||
authors: [
|
||||
"pukkamustard <pukkamustard@posteo.net>"
|
||||
"swrup <swrup@protonmail.com>"
|
||||
"pena <pena@kumikode.org>"
|
||||
]
|
||||
license: "BSD-2-Clause"
|
||||
tags: ["leaflet" "javascript" "bindings" "interactive" "map" "openstreetmap"]
|
||||
homepage: "https://forge.kumikode.org/kumikode/leaflet"
|
||||
bug-reports: "https://forge.kumikode.org/kumikode/leaflet/issues"
|
||||
depends: [
|
||||
"dune" {>= "2.9"}
|
||||
"ocaml" {>= "4.08"}
|
||||
"brr"
|
||||
"js_of_ocaml"
|
||||
"dune-site"
|
||||
"tiny_httpd" {with-test}
|
||||
"odoc" {with-doc}
|
||||
]
|
||||
build: [
|
||||
|
|
@ -30,4 +39,4 @@ build: [
|
|||
]
|
||||
["dune" "install" "-p" name "--create-install-files" name]
|
||||
]
|
||||
dev-repo: "TODO/leaflet"
|
||||
dev-repo: "git+https://forge.kumikode.org/kumikode/leaflet.git"
|
||||
|
|
|
|||
26
src/dune
26
src/dune
|
|
@ -1,7 +1,25 @@
|
|||
(library
|
||||
(name leaflet)
|
||||
(public_name leaflet)
|
||||
(modules ev latlng geojson_layer tile_layer popup marker map global layer)
|
||||
(libraries brr js_of_ocaml)
|
||||
(modules event global latlng layer map marker popup point icon)
|
||||
(private_modules global)
|
||||
(libraries brr)
|
||||
(js_of_ocaml
|
||||
(javascript_files leaflet.js)))
|
||||
(javascript_files vendor/leaflet.js)))
|
||||
|
||||
(install
|
||||
(section
|
||||
(site
|
||||
(leaflet css)))
|
||||
(files
|
||||
(vendor/leaflet.css as leaflet.css)))
|
||||
|
||||
(install
|
||||
(section
|
||||
(site
|
||||
(leaflet images)))
|
||||
(files
|
||||
(vendor/images/layers-2x.png as images/layers-2x.png)
|
||||
(vendor/images/layers.png as images/layers.png)
|
||||
(vendor/images/marker-icon-2x.png as images/marker-icon-2x.png)
|
||||
(vendor/images/marker-icon.png as images/marker-icon.png)
|
||||
(vendor/images/marker-shadow.png as images/marker-shadow.png)))
|
||||
|
|
|
|||
31
src/ev.ml
31
src/ev.ml
|
|
@ -1,31 +0,0 @@
|
|||
module Make () = struct
|
||||
type t = Jv.t
|
||||
|
||||
let type' e = Jv.get e "type" |> Jv.to_string
|
||||
|
||||
let target e = Jv.get e "target" |> Brr.Ev.target_of_jv
|
||||
|
||||
let source_target e = Jv.get e "sourceTarget" |> Brr.Ev.target_of_jv
|
||||
|
||||
let propagated_from e = Jv.get e "propagatedFrom"
|
||||
|
||||
let latlng e = Latlng.of_jv_t @@ Jv.get e "latlng"
|
||||
|
||||
let layer_point e = Jv.get e "layerPoint"
|
||||
|
||||
let container_point e = Jv.get e "containerPoint"
|
||||
|
||||
let original_event e = Jv.get e "originalEvent"
|
||||
|
||||
let message e = Jv.get e "message" |> Jv.to_string
|
||||
|
||||
let code e = Jv.get e "code" |> Jv.to_int
|
||||
end
|
||||
|
||||
module Event = Make ()
|
||||
|
||||
module Keyboard = Make ()
|
||||
|
||||
module Mouse = Make ()
|
||||
|
||||
module Error = Make ()
|
||||
66
src/ev.mli
66
src/ev.mli
|
|
@ -1,66 +0,0 @@
|
|||
module Event : sig
|
||||
type t
|
||||
|
||||
val type' : t -> string
|
||||
|
||||
val target : t -> Brr.Ev.target
|
||||
|
||||
val source_target : t -> Brr.Ev.target
|
||||
|
||||
(* TODO this should return Point *)
|
||||
val propagated_from : t -> Jv.t
|
||||
end
|
||||
|
||||
module Keyboard : sig
|
||||
type t
|
||||
|
||||
val type' : t -> string
|
||||
|
||||
val target : t -> Brr.Ev.target
|
||||
|
||||
val source_target : t -> Brr.Ev.target
|
||||
|
||||
val propagated_from : t -> Jv.t
|
||||
|
||||
(* TODO this should return BrrDomEvent*)
|
||||
val original_event : t -> Jv.t
|
||||
end
|
||||
|
||||
module Mouse : sig
|
||||
type t
|
||||
|
||||
val type' : t -> string
|
||||
|
||||
val target : t -> Brr.Ev.target
|
||||
|
||||
val source_target : t -> Brr.Ev.target
|
||||
|
||||
val propagated_from : t -> Jv.t
|
||||
|
||||
val latlng : t -> Latlng.t
|
||||
|
||||
(* TODO this should return Point *)
|
||||
val layer_point : t -> Jv.t
|
||||
|
||||
(* TODO this should return Point *)
|
||||
val container_point : t -> Jv.t
|
||||
|
||||
(* TODO this should return BrrDomEvent*)
|
||||
val original_event : t -> Jv.t
|
||||
end
|
||||
|
||||
module Error : sig
|
||||
type t
|
||||
|
||||
val type' : t -> string
|
||||
|
||||
val target : t -> Brr.Ev.target
|
||||
|
||||
val source_target : t -> Brr.Ev.target
|
||||
|
||||
val propagated_from : t -> Jv.t
|
||||
|
||||
val message : t -> string
|
||||
|
||||
val code : t -> int
|
||||
end
|
||||
61
src/event.ml
Normal file
61
src/event.ml
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type _ t =
|
||||
| Keyboard : Jv.t -> [> `Keyboard ] t
|
||||
| Mouse : Jv.t -> [> `Mouse ] t
|
||||
| Error : Jv.t -> [> `Error ] t
|
||||
| Basic : Jv.t -> [> `Basic ] t
|
||||
|
||||
type _ sub =
|
||||
| Click : [> `Mouse ] sub
|
||||
| Move_end : [> `Basic ] sub
|
||||
| Zoom_end : [> `Basic ] sub
|
||||
|
||||
let of_jv : type kind. kind sub -> Jv.t -> kind t =
|
||||
fun tag e ->
|
||||
match tag with Click -> Mouse e | Move_end -> Basic e | Zoom_end -> Basic e
|
||||
|
||||
let sub_to_string : type kind. kind sub -> string = function
|
||||
| Click -> "click"
|
||||
| Move_end -> "moveend"
|
||||
| Zoom_end -> "zoomend"
|
||||
|
||||
(** Basic events *)
|
||||
|
||||
let get_type : type kind. kind t -> string = function
|
||||
| Keyboard e | Mouse e | Error e | Basic e -> Jv.get e "type" |> Jv.to_string
|
||||
|
||||
let target : type kind. kind t -> Brr.Ev.target = function
|
||||
| Keyboard e | Mouse e | Error e | Basic e ->
|
||||
Jv.get e "target" |> Brr.Ev.target_of_jv
|
||||
|
||||
let source_target : type kind. kind t -> Brr.Ev.target = function
|
||||
| Keyboard e | Mouse e | Error e | Basic e ->
|
||||
Jv.get e "sourceTarget" |> Brr.Ev.target_of_jv
|
||||
|
||||
let propagated_from : type kind. kind t -> Jv.t = function
|
||||
| Keyboard e | Mouse e | Error e | Basic e -> Jv.get e "propagatedFrom"
|
||||
|
||||
(** Keyboard & Mouse events *)
|
||||
|
||||
let original_event : [ `Keyboard | `Mouse ] t -> Jv.t = function
|
||||
| Keyboard e | Mouse e -> Jv.get e "originalEvent"
|
||||
|
||||
(** Mouse events *)
|
||||
|
||||
let container_point : [ `Mouse ] t -> Point.t = function
|
||||
| Mouse e -> Jv.get e "containerPoint" |> Point.of_jv
|
||||
|
||||
let layer_point : [ `Mouse ] t -> Point.t = function
|
||||
| Mouse e -> Jv.get e "layerPoint" |> Point.of_jv
|
||||
|
||||
let latlng : [ `Mouse ] t -> Latlng.t = function
|
||||
| Mouse e -> Jv.get e "latlng" |> Latlng.of_jv
|
||||
|
||||
(** Error events *)
|
||||
|
||||
let code : [ `Error ] t -> int = function
|
||||
| Error e -> Jv.get e "code" |> Jv.to_int
|
||||
|
||||
let message : [ `Error ] t -> string = function
|
||||
| Error e -> Jv.get e "message" |> Jv.to_string
|
||||
44
src/event.mli
Normal file
44
src/event.mli
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type _ t =
|
||||
| Keyboard : Jv.t -> [> `Keyboard ] t
|
||||
| Mouse : Jv.t -> [> `Mouse ] t
|
||||
| Error : Jv.t -> [> `Error ] t
|
||||
| Basic : Jv.t -> [> `Basic ] t
|
||||
|
||||
type _ sub =
|
||||
| Click : [> `Mouse ] sub
|
||||
| Move_end : [> `Basic ] sub
|
||||
| Zoom_end : [> `Basic ] sub
|
||||
|
||||
val of_jv : 'a sub -> Jv.t -> 'a t
|
||||
|
||||
val sub_to_string : _ sub -> string
|
||||
|
||||
(** Basic events *)
|
||||
|
||||
val get_type : _ t -> string
|
||||
|
||||
val target : _ t -> Brr.Ev.target
|
||||
|
||||
val source_target : _ t -> Brr.Ev.target
|
||||
|
||||
val propagated_from : _ t -> Jv.t
|
||||
|
||||
(** Keyboard & Mouse events *)
|
||||
|
||||
val original_event : [ `Keyboard | `Mouse ] t -> Jv.t
|
||||
|
||||
(** Mouse events *)
|
||||
|
||||
val container_point : [ `Mouse ] t -> Point.t
|
||||
|
||||
val layer_point : [ `Mouse ] t -> Point.t
|
||||
|
||||
val latlng : [ `Mouse ] t -> Latlng.t
|
||||
|
||||
(** Error events *)
|
||||
|
||||
val code : [ `Error ] t -> int
|
||||
|
||||
val message : [ `Error ] t -> string
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
include Layer
|
||||
|
||||
let create ?(options = Jv.null) geojson =
|
||||
of_jv_t @@ Jv.call Global.leaflet "geoJSON" [| geojson; options |]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
type t
|
||||
|
||||
val create : ?options:Jv.t -> Jv.t -> t
|
||||
|
||||
val add_to : Map.t -> t -> unit
|
||||
|
||||
val remove : t -> unit
|
||||
|
||||
val remove_from : Map.t -> t -> unit
|
||||
|
||||
val bind_popup : Brr.El.t -> t -> unit
|
||||
|
||||
val unbind_popup : t -> unit
|
||||
|
||||
val open_popup : t -> unit
|
||||
|
||||
val close_popup : t -> unit
|
||||
|
||||
val get_popup : t -> Popup.t
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
let leaflet =
|
||||
match Jv.(find global "L") with
|
||||
| Some l -> l
|
||||
|
|
|
|||
74
src/icon.ml
Normal file
74
src/icon.ml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t = Jv.t
|
||||
|
||||
let to_jv = Fun.id
|
||||
|
||||
let of_jv = Fun.id
|
||||
|
||||
type opt =
|
||||
| Icon_retina_url of string
|
||||
| Icon_size of Point.t
|
||||
| Icon_anchor of Point.t
|
||||
| Popup_anchor of Point.t
|
||||
| Tooltip_anchor of Point.t
|
||||
| Shadow_url of string
|
||||
| Shadow_retina_url of string
|
||||
| Shadow_size of Point.t
|
||||
| Shadow_anchor of Point.t
|
||||
| Class_name of string
|
||||
| Cross_origin of string option
|
||||
|
||||
let to_string = function
|
||||
| Icon_retina_url _ -> "iconRetinaUrl"
|
||||
| Icon_size _ -> "iconSize"
|
||||
| Icon_anchor _ -> "iconAnchor"
|
||||
| Popup_anchor _ -> "popupAnchor"
|
||||
| Tooltip_anchor _ -> "tooltipAnchor"
|
||||
| Shadow_url _ -> "shadowUrl"
|
||||
| Shadow_retina_url _ -> "shadowRetinaUrl"
|
||||
| Shadow_size _ -> "shadowSize"
|
||||
| Shadow_anchor _ -> "shadowAnchor"
|
||||
| Class_name _ -> "className"
|
||||
| Cross_origin _ -> "crossOrigin"
|
||||
|
||||
let opt_to_jv = function
|
||||
| Icon_size p
|
||||
| Icon_anchor p
|
||||
| Popup_anchor p
|
||||
| Tooltip_anchor p
|
||||
| Shadow_size p
|
||||
| Shadow_anchor p ->
|
||||
Point.to_jv p
|
||||
| Icon_retina_url s | Shadow_url s | Shadow_retina_url s | Class_name s ->
|
||||
Jv.of_string s
|
||||
| Cross_origin o -> (
|
||||
match o with Some s -> Jv.of_string s | None -> Jv.of_bool false )
|
||||
|
||||
let create icon_url options =
|
||||
let l = Array.map (fun o -> (to_string o, opt_to_jv o)) options in
|
||||
let l = Array.append [| ("iconUrl", Jv.of_string icon_url) |] l in
|
||||
Jv.call Global.leaflet "icon" [| Jv.obj l |]
|
||||
|
||||
let create_div ~html ~bg_pos options =
|
||||
let l = Array.map (fun o -> (to_string o, opt_to_jv o)) options in
|
||||
let div_options =
|
||||
let html =
|
||||
match html with
|
||||
| None -> []
|
||||
| Some html -> [ ("html", Jv.of_string html) ]
|
||||
in
|
||||
let bg_pos =
|
||||
match bg_pos with
|
||||
| None -> []
|
||||
| Some bg_pos -> [ ("bgPos", Point.to_jv bg_pos) ]
|
||||
in
|
||||
html @ bg_pos |> Array.of_list
|
||||
in
|
||||
let l = Array.append div_options l in
|
||||
Jv.call Global.leaflet "divIcon" [| Jv.obj l |]
|
||||
|
||||
let set_default_image_path s =
|
||||
let icon = Jv.get Global.leaflet "Icon" in
|
||||
let icon_default = Jv.get icon "Default" in
|
||||
Jv.set icon_default "imagePath" (Jv.of_string s)
|
||||
36
src/icon.mli
Normal file
36
src/icon.mli
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t
|
||||
|
||||
(** [to_jv o] is [o] as {!Jv.t} *)
|
||||
val to_jv : t -> Jv.t
|
||||
|
||||
(** [of_jv o] is [o] as {!Icon.t} *)
|
||||
val of_jv : Jv.t -> t
|
||||
|
||||
(** type for icon option used to create an icon*)
|
||||
type opt =
|
||||
| Icon_retina_url of string
|
||||
| Icon_size of Point.t
|
||||
| Icon_anchor of Point.t
|
||||
| Popup_anchor of Point.t
|
||||
| Tooltip_anchor of Point.t
|
||||
| Shadow_url of string
|
||||
| Shadow_retina_url of string
|
||||
| Shadow_size of Point.t
|
||||
| Shadow_anchor of Point.t
|
||||
| Class_name of string
|
||||
| Cross_origin of string option
|
||||
|
||||
(** [create icon_url options] Creates an icon instance with the given [options],
|
||||
and the required `iconUrl` option set to [icon_url] *)
|
||||
val create : string -> opt array -> t
|
||||
|
||||
(** [create_div ~html ~bg_pos options] Creates an DivIcon instance with the
|
||||
given [options], [bg_pos] is the optional relative position of the
|
||||
background, in pixels [html] is custom HTML code to put inside the div
|
||||
element, empty by default. *)
|
||||
val create_div : html:string option -> bg_pos:Point.t option -> opt array -> t
|
||||
|
||||
(** Sets the path of the default icon *)
|
||||
val set_default_image_path : string -> unit
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t = Jv.t
|
||||
|
||||
let create lat lng =
|
||||
let create ~lat ~lng =
|
||||
Jv.call Global.leaflet "latLng" [| Jv.of_float lat; Jv.of_float lng |]
|
||||
|
||||
let lat latlng = Jv.get latlng "lat" |> Jv.to_float
|
||||
|
|
@ -9,6 +11,6 @@ let lng latlng = Jv.get latlng "lng" |> Jv.to_float
|
|||
|
||||
let equals a b = Jv.call a "equals" [| b |] |> Jv.to_bool
|
||||
|
||||
let of_jv_t = Fun.id
|
||||
let of_jv = Fun.id
|
||||
|
||||
let to_jv_t = Fun.id
|
||||
let to_jv = Fun.id
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t
|
||||
|
||||
val create : float -> float -> t
|
||||
(** [create lat lng] is an object representing a geographical point with the
|
||||
given latitude and longitude *)
|
||||
val create : lat:float -> lng:float -> t
|
||||
|
||||
(** [lat o] is the latitude of [o] *)
|
||||
val lat : t -> float
|
||||
|
||||
(** [lng o] is the longitude of [o] *)
|
||||
val lng : t -> float
|
||||
|
||||
(** [equals a b] is true iff [a] and [b] is at the same position (within a small
|
||||
margin of error) *)
|
||||
val equals : t -> t -> bool
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
(** [of_jv jv] is [jv] as a [Latlng.t] *)
|
||||
val of_jv : Jv.t -> t
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
(** [to_jv o] is [o] as a {!Jv.t} *)
|
||||
val to_jv : t -> Jv.t
|
||||
|
|
|
|||
247
src/layer.ml
247
src/layer.ml
|
|
@ -1,23 +1,244 @@
|
|||
type t = Jv.t
|
||||
(* BSD-2-Clause License *)
|
||||
|
||||
let add_to map layer = ignore @@ Jv.call layer "addTo" [| Map.to_jv_t map |]
|
||||
type _ t =
|
||||
| Basic : Jv.t -> [> `Basic ] t
|
||||
| Geojson : Jv.t -> [> `Geojson ] t
|
||||
| Marker : Jv.t -> [> `Marker ] t
|
||||
| Tile : Jv.t -> [> `Tile ] t
|
||||
| Vector : Jv.t -> [> `Vector ] t
|
||||
|
||||
let remove layer = ignore @@ Jv.call layer "remove" [||]
|
||||
type _ sub =
|
||||
| Basic : [> `Basic ] sub
|
||||
| Geojson : [> `Geojson ] sub
|
||||
| Marker : [> `Marker ] sub
|
||||
| Tile : [> `Tile ] sub
|
||||
| Vector : [> `Vector ] sub
|
||||
|
||||
let remove_from map layer =
|
||||
ignore @@ Jv.call layer "removeFrom" [| Map.to_jv_t map |]
|
||||
(** Basic layers *)
|
||||
|
||||
let bind_popup el layer =
|
||||
ignore @@ Jv.call layer "bindPopup" [| Brr.El.to_jv el |]
|
||||
let add_to : type kind. Map.t -> kind t -> unit =
|
||||
fun map -> function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "addTo" [| Map.to_jv map |] in
|
||||
()
|
||||
|
||||
let unbind_popup layer = ignore @@ Jv.call layer "unbindPopup" [||]
|
||||
let remove : type kind. kind t -> unit = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "remove" [||] in
|
||||
()
|
||||
|
||||
let open_popup layer = ignore @@ Jv.call layer "openPopup" [||]
|
||||
let remove_from : type kind. Map.t -> kind t -> unit =
|
||||
fun map -> function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "removeFrom" [| Map.to_jv map |] in
|
||||
()
|
||||
|
||||
let close_popup layer = ignore @@ Jv.call layer "closePopup" [||]
|
||||
let bind_popup : type kind. Popup.t -> kind t -> unit =
|
||||
fun popup -> function
|
||||
| Basic layer | Geojson layer | Marker layer | Tile layer | Vector layer ->
|
||||
let (_ : Jv.t) = Jv.call layer "bindPopup" [| Popup.to_jv popup |] in
|
||||
()
|
||||
|
||||
let get_popup layer = Popup.of_jv_t @@ Jv.call layer "getPopup" [||]
|
||||
let unbind_popup : type kind. kind t -> unit = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "unbindPopup" [||] in
|
||||
()
|
||||
|
||||
let of_jv_t = Fun.id
|
||||
let open_popup : type kind. kind t -> unit = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "openPopup" [||] in
|
||||
()
|
||||
|
||||
let to_jv_t = Fun.id
|
||||
let close_popup : type kind. kind t -> unit = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
let (_ : Jv.t) = Jv.call l "closePopup" [||] in
|
||||
()
|
||||
|
||||
let get_popup : type kind. kind t -> Popup.t = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l ->
|
||||
Jv.call l "getPopup" [||] |> Popup.of_jv
|
||||
|
||||
let to_jv : type kind. kind t -> Jv.t = function
|
||||
| Basic l | Geojson l | Marker l | Tile l | Vector l -> l
|
||||
|
||||
let of_jv : type kind. kind sub -> Jv.t -> kind t =
|
||||
fun tag l ->
|
||||
match tag with
|
||||
| Basic -> Basic l
|
||||
| Geojson -> Geojson l
|
||||
| Marker -> Marker l
|
||||
| Tile -> Tile l
|
||||
| Vector -> Vector l
|
||||
|
||||
let on : type kind. kind Event.sub -> (kind Event.t -> 'b) -> 'c t -> unit =
|
||||
fun event handler layer ->
|
||||
let name = Event.sub_to_string event in
|
||||
let handler v = handler @@ Event.of_jv event v in
|
||||
let (_ : Jv.t) =
|
||||
Jv.call (to_jv layer) "on" [| Jv.of_string name; Jv.repr handler |]
|
||||
in
|
||||
()
|
||||
|
||||
(** Geojson layers *)
|
||||
|
||||
type geojson_opt =
|
||||
| Point_to_layer of (Jv.t -> Latlng.t -> [ `Marker ] t)
|
||||
| Style of (Jv.t -> unit)
|
||||
| On_each_feature of (Jv.t -> [ `Geojson ] t -> unit)
|
||||
| Filter of (Jv.t -> bool)
|
||||
| Coords_to_latlng of (Jv.t -> Latlng.t)
|
||||
| Markers_inherit_options of bool
|
||||
|
||||
let geojson_opt_to_string = function
|
||||
| Point_to_layer _ -> "pointToLayer"
|
||||
| Style _ -> "style"
|
||||
| On_each_feature _ -> "onEachFeature"
|
||||
| Filter _ -> "filter"
|
||||
| Coords_to_latlng _ -> "coordsToLatLng"
|
||||
| Markers_inherit_options _ -> "markersInheritOptions"
|
||||
|
||||
let geojson_opt_to_jv = function
|
||||
| Markers_inherit_options b -> Jv.of_bool b
|
||||
| Point_to_layer f ->
|
||||
(* the marker returned by `pointToLayer` is used internally by leaflet so we neet to unwrap it to a Jv.t *)
|
||||
Jv.repr (fun geojsonpoint latlng -> to_jv @@ f geojsonpoint latlng)
|
||||
| Style f -> Jv.repr f
|
||||
| On_each_feature f ->
|
||||
(* we need to wrap the Jv.t *)
|
||||
let f feature jv = jv |> of_jv Geojson |> f feature in
|
||||
Jv.repr f
|
||||
| Filter f -> Jv.repr f
|
||||
| Coords_to_latlng f -> Jv.repr f
|
||||
|
||||
let create_geojson : Brr.Json.t -> geojson_opt array -> [ `Geojson ] t =
|
||||
fun geojson options ->
|
||||
let l =
|
||||
Array.map (fun o -> (geojson_opt_to_string o, geojson_opt_to_jv o)) options
|
||||
in
|
||||
let jv_t = Jv.call Global.leaflet "geoJSON" [| geojson; Jv.obj l |] in
|
||||
Geojson jv_t
|
||||
|
||||
(** Tile layers *)
|
||||
|
||||
type tile_layer_opt =
|
||||
| Min_zoom of int
|
||||
| Max_zoom of int
|
||||
| Subdomains of string array
|
||||
| Error_tile_url of string
|
||||
| Zoom_offset of int
|
||||
| Tms of bool
|
||||
| Zoom_reverse of bool
|
||||
| Detect_retina of bool
|
||||
| (* TODO allow string for those two
|
||||
"Whether the crossOrigin attribute will be added to the tiles. If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data. Refer to CORS Settings for valid String values."
|
||||
*)
|
||||
Cross_origin of bool
|
||||
| Referrer_policy of bool
|
||||
| (* GridLayer options *)
|
||||
Tile_size of Point.t
|
||||
| Opacity of float
|
||||
| Update_when_idle of bool
|
||||
| Update_when_zooming of bool
|
||||
| Update_interval of int
|
||||
| Z_index of int
|
||||
| Bounds of (* LatLngBounds *) Latlng.t * Latlng.t
|
||||
| Max_native_zoom of int
|
||||
| Min_native_zoom of int
|
||||
| No_wrap of bool
|
||||
| Pane of string
|
||||
| Class_name of string
|
||||
| Keep_buffer of int
|
||||
|
||||
let tile_layer_opt_to_string = function
|
||||
| Min_zoom _ -> "minZoom"
|
||||
| Max_zoom _ -> "maxZoom"
|
||||
| Subdomains _ -> "subdomains"
|
||||
| Error_tile_url _ -> "errorTileUrl"
|
||||
| Zoom_offset _ -> "zoomOffset"
|
||||
| Tms _ -> "tms"
|
||||
| Zoom_reverse _ -> "zoomReverse"
|
||||
| Detect_retina _ -> "detectRetina"
|
||||
| Cross_origin _ -> "crossOrigin"
|
||||
| Referrer_policy _ -> "referrerPolicy"
|
||||
| Tile_size _ -> "tileSize"
|
||||
| Opacity _ -> "opacity"
|
||||
| Update_when_idle _ -> "updateWhenIdle"
|
||||
| Update_when_zooming _ -> "updateWhenZooming"
|
||||
| Update_interval _ -> "updateInterval"
|
||||
| Z_index _ -> "zIndex"
|
||||
| Bounds _ -> "bounds"
|
||||
| Max_native_zoom _ -> "maxNativeZoom"
|
||||
| Min_native_zoom _ -> "minNativeZoom"
|
||||
| No_wrap _ -> "noWrap"
|
||||
| Pane _ -> "pane"
|
||||
| Class_name _ -> "className"
|
||||
| Keep_buffer _ -> "keepBuffer"
|
||||
|
||||
let tile_layer_opt_to_jv = function
|
||||
| Min_zoom o
|
||||
| Max_zoom o
|
||||
| Zoom_offset o
|
||||
| Update_interval o
|
||||
| Z_index o
|
||||
| Keep_buffer o
|
||||
| Min_native_zoom o
|
||||
| Max_native_zoom o ->
|
||||
Jv.of_int o
|
||||
| Tms o
|
||||
| Zoom_reverse o
|
||||
| Detect_retina o
|
||||
| Cross_origin o
|
||||
| Referrer_policy o
|
||||
| Update_when_idle o
|
||||
| Update_when_zooming o
|
||||
| No_wrap o ->
|
||||
Jv.of_bool o
|
||||
| Error_tile_url o | Pane o | Class_name o -> Jv.of_string o
|
||||
| Subdomains o -> Jv.of_array Jv.of_string o
|
||||
| Opacity o -> Jv.of_float o
|
||||
| Tile_size o -> Point.to_jv o
|
||||
| Bounds (a, b) ->
|
||||
(* create the actual LatlngBounds from the pair *)
|
||||
Jv.call Global.leaflet "latLngBounds" [| Latlng.to_jv a; Latlng.to_jv b |]
|
||||
|
||||
let create_tile :
|
||||
string -> attribution:string -> tile_layer_opt array -> [ `Tile ] t =
|
||||
fun url ~attribution options ->
|
||||
let arr =
|
||||
Array.append
|
||||
[| ("attribution", Jv.of_string attribution) |]
|
||||
(Array.map
|
||||
(fun o -> (tile_layer_opt_to_string o, tile_layer_opt_to_jv o))
|
||||
options )
|
||||
in
|
||||
let jv_t =
|
||||
Jv.call Global.leaflet "tileLayer" [| Jv.of_string url; Jv.obj arr |]
|
||||
in
|
||||
Tile jv_t
|
||||
|
||||
let create_tile_osm : tile_layer_opt array -> [ `Tile ] t =
|
||||
fun options ->
|
||||
let url = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" in
|
||||
let attribution =
|
||||
"© <a \
|
||||
href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> \
|
||||
contributors"
|
||||
in
|
||||
create_tile url ~attribution options
|
||||
|
||||
(* Vector Layers *)
|
||||
|
||||
(* TODO add options *)
|
||||
|
||||
let create_polyline : Latlng.t array -> [ `Vector ] t =
|
||||
fun l ->
|
||||
let l = Jv.of_array Latlng.to_jv l in
|
||||
let jv_t = Jv.call Global.leaflet "polyline" [| l |] in
|
||||
Vector jv_t
|
||||
|
||||
let create_circle_marker : Latlng.t -> float -> [ `Vector ] t =
|
||||
fun center radius ->
|
||||
let center = Latlng.to_jv center in
|
||||
let arr = [| ("radius", Jv.of_float radius) |] in
|
||||
let jv_t = Jv.call Global.leaflet "circleMarker" [| center; Jv.obj arr |] in
|
||||
Vector jv_t
|
||||
|
|
|
|||
109
src/layer.mli
109
src/layer.mli
|
|
@ -1,21 +1,108 @@
|
|||
type t
|
||||
(* BSD-2-Clause License *)
|
||||
|
||||
val add_to : Map.t -> t -> unit
|
||||
type _ t =
|
||||
| Basic : Jv.t -> [> `Basic ] t
|
||||
| Geojson : Jv.t -> [> `Geojson ] t
|
||||
| Marker : Jv.t -> [> `Marker ] t
|
||||
| Tile : Jv.t -> [> `Tile ] t
|
||||
| Vector : Jv.t -> [> `Vector ] t
|
||||
|
||||
val remove : t -> unit
|
||||
type _ sub =
|
||||
| Basic : [> `Basic ] sub
|
||||
| Geojson : [> `Geojson ] sub
|
||||
| Marker : [> `Marker ] sub
|
||||
| Tile : [> `Tile ] sub
|
||||
| Vector : [> `Vector ] sub
|
||||
|
||||
val remove_from : Map.t -> t -> unit
|
||||
(** Basic layers *)
|
||||
|
||||
val bind_popup : Brr.El.t -> t -> unit
|
||||
(** [add_to map layer] adds [layer] to [map] *)
|
||||
val add_to : Map.t -> _ t -> unit
|
||||
|
||||
val unbind_popup : t -> unit
|
||||
(** [remove layer] removes [layer] from the map it is currently active on *)
|
||||
val remove : _ t -> unit
|
||||
|
||||
val open_popup : t -> unit
|
||||
(** [remove_from map layer] removes [layer] from [map] *)
|
||||
val remove_from : Map.t -> _ t -> unit
|
||||
|
||||
val close_popup : t -> unit
|
||||
(** [bind_popup popup layer] binds [popup] to [layer] *)
|
||||
val bind_popup : Popup.t -> _ t -> unit
|
||||
|
||||
val get_popup : t -> Popup.t
|
||||
(** [unbind_popup layer] unbinds the popup bound to [layer] *)
|
||||
val unbind_popup : _ t -> unit
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
(** [open_popup layer] opens the popup bound to [layer] *)
|
||||
val open_popup : _ t -> unit
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
(** [close_popup layer] closes the popup bound to [layer] *)
|
||||
val close_popup : _ t -> unit
|
||||
|
||||
(** [get_popup layer] is the popup bound to [layer] *)
|
||||
val get_popup : _ t -> Popup.t
|
||||
|
||||
(** [to_jv o] is [o] as a {!Jv.t} *)
|
||||
val to_jv : _ t -> Jv.t
|
||||
|
||||
(** [of_jv tag o] is [o] as a [tag t] *)
|
||||
val of_jv : 'a sub -> Jv.t -> 'a t
|
||||
|
||||
(** [on event handler layer] add an event listener on [layer] for event [event]
|
||||
with handler [handler] *)
|
||||
val on : 'a Event.sub -> ('a Event.t -> 'b) -> 'c t -> unit
|
||||
|
||||
(** Geojson layers *)
|
||||
|
||||
(** type for geojson option, used to create geojson *)
|
||||
type geojson_opt =
|
||||
| Point_to_layer of (Jv.t -> Latlng.t -> [ `Marker ] t)
|
||||
| Style of (Jv.t -> unit)
|
||||
| On_each_feature of (Jv.t -> [ `Geojson ] t -> unit)
|
||||
| Filter of (Jv.t -> bool)
|
||||
| Coords_to_latlng of (Jv.t -> Latlng.t)
|
||||
| Markers_inherit_options of bool
|
||||
|
||||
(** [create_geojson geojson] is a new geojson layer *)
|
||||
val create_geojson : Brr.Json.t -> geojson_opt array -> [ `Geojson ] t
|
||||
|
||||
(** Tile layers *)
|
||||
|
||||
type tile_layer_opt =
|
||||
| Min_zoom of int
|
||||
| Max_zoom of int
|
||||
| Subdomains of string array
|
||||
| Error_tile_url of string
|
||||
| Zoom_offset of int
|
||||
| Tms of bool
|
||||
| Zoom_reverse of bool
|
||||
| Detect_retina of bool
|
||||
| Cross_origin of bool
|
||||
| Referrer_policy of bool
|
||||
| Tile_size of Point.t
|
||||
| Opacity of float
|
||||
| Update_when_idle of bool
|
||||
| Update_when_zooming of bool
|
||||
| Update_interval of int
|
||||
| Z_index of int
|
||||
| Bounds of (* LatLngBounds *) Latlng.t * Latlng.t
|
||||
| Max_native_zoom of int
|
||||
| Min_native_zoom of int
|
||||
| No_wrap of bool
|
||||
| Pane of string
|
||||
| Class_name of string
|
||||
| Keep_buffer of int
|
||||
|
||||
(** [create_tile url attribution opts] create a new tile layer *)
|
||||
val create_tile :
|
||||
string -> attribution:string -> tile_layer_opt array -> [ `Tile ] t
|
||||
|
||||
(** [create_tile_osm opts] create a new tile layer with tile server and
|
||||
attribution set to [openstreetmap.org]. See
|
||||
{:https://wiki.openstreetmap.org/wiki/Tile_servers} *)
|
||||
val create_tile_osm : tile_layer_opt array -> [ `Tile ] t
|
||||
|
||||
(** [create_polyline l] create a polyline layer from [l] *)
|
||||
val create_polyline : Latlng.t array -> [ `Vector ] t
|
||||
|
||||
(** [create_circle_marker c r] create a cirecle marker layer with center [c] and
|
||||
radius [r] *)
|
||||
val create_circle_marker : Latlng.t -> float -> [ `Vector ] t
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +0,0 @@
|
|||
SPDX-FileCopyrightText: 2010-2021 Vladimir Agafonkin
|
||||
|
||||
SPDX-License-Identifier: BSD-2-Clause
|
||||
76
src/map.ml
76
src/map.ml
|
|
@ -1,46 +1,58 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t = Jv.t
|
||||
|
||||
module Event = struct
|
||||
let to_brr s = s |> Jstr.v |> Brr.Ev.Type.create
|
||||
let of_jv = Fun.id
|
||||
|
||||
let click = to_brr "click"
|
||||
let to_jv = Fun.id
|
||||
|
||||
let moveend = to_brr "moveend"
|
||||
let create_on ?(options = Jv.null) id =
|
||||
Jv.call Global.leaflet "map" [| Jv.of_string id; options |]
|
||||
|
||||
let zoomend = to_brr "zoomend"
|
||||
end
|
||||
let create_from_div ?(options = Jv.null) container =
|
||||
if Brr.El.has_tag_name Brr.El.Name.div container then
|
||||
Jv.call Global.leaflet "map" [| Brr.El.to_jv container; options |]
|
||||
else failwith "container is not a <div>"
|
||||
|
||||
let of_jv_t = Fun.id
|
||||
let invalidate_size map =
|
||||
let (_ : Jv.t) = Jv.call map "invalidateSize" [| Jv.true' |] in
|
||||
()
|
||||
|
||||
let to_jv_t = Fun.id
|
||||
let fit_world map =
|
||||
let (_ : Jv.t) = Jv.call map "fitWorld" [||] in
|
||||
()
|
||||
|
||||
let create ?(options = Jv.null) container_id =
|
||||
Jv.call Global.leaflet "map" [| Jv.of_string container_id; options |]
|
||||
let get_container map = Jv.call (to_jv map) "getContainer" [||] |> Brr.El.of_jv
|
||||
|
||||
let invalidate_size map = ignore @@ Jv.call map "invalidateSize" [| Jv.true' |]
|
||||
let set_view latlng ~zoom map =
|
||||
let latlng = Latlng.to_jv latlng in
|
||||
let (_ : Jv.t) =
|
||||
match zoom with
|
||||
| None -> Jv.call map "setView" [| latlng |]
|
||||
| Some zoom -> Jv.call map "setView" [| latlng; Jv.of_int zoom |]
|
||||
in
|
||||
()
|
||||
|
||||
let fit_world map = ignore @@ Jv.call map "fitWorld" [||]
|
||||
let on : type kind. kind Event.sub -> (kind Event.t -> unit) -> t -> unit =
|
||||
fun event handler map ->
|
||||
let name = Event.sub_to_string event in
|
||||
let handler v = handler @@ Event.of_jv event v in
|
||||
let (_ : Jv.t) = Jv.call map "on" [| Jv.of_string name; Jv.repr handler |] in
|
||||
()
|
||||
|
||||
let get_container map =
|
||||
Jv.call (to_jv_t map) "getContainer" [||] |> Brr.El.of_jv
|
||||
|
||||
let set_view latlng ?zoom map =
|
||||
let latlng = Latlng.to_jv_t latlng in
|
||||
ignore
|
||||
@@
|
||||
match zoom with
|
||||
| None -> Jv.call map "setView" [| latlng |]
|
||||
| Some zoom -> Jv.call map "setView" [| latlng; Jv.of_int zoom |]
|
||||
|
||||
let as_target map = Brr.Ev.target_of_jv map
|
||||
|
||||
let on ~event ~handler map =
|
||||
let name = Brr.Ev.Type.name event |> Jv.of_jstr in
|
||||
ignore @@ Jv.call map "on" [| name; Jv.repr handler |]
|
||||
|
||||
let get_center map = Latlng.of_jv_t @@ Jv.call map "getCenter" [||]
|
||||
let get_center map = Latlng.of_jv @@ Jv.call map "getCenter" [||]
|
||||
|
||||
let get_zoom map = Jv.call map "getZoom" [||] |> Jv.to_int
|
||||
|
||||
let wrapped_latlng latlng map =
|
||||
Latlng.of_jv_t @@ Jv.call map "wrapLatLng" [| Latlng.to_jv_t latlng |]
|
||||
let wrap_latlng latlng map =
|
||||
Latlng.of_jv @@ Jv.call map "wrapLatLng" [| Latlng.to_jv latlng |]
|
||||
|
||||
let open_popup popup map =
|
||||
ignore @@ Jv.call map "openPopup" [| Popup.to_jv popup |]
|
||||
|
||||
let close_popup popup map =
|
||||
ignore
|
||||
@@
|
||||
match popup with
|
||||
| None -> Jv.call map "closePopup" [||]
|
||||
| Some popup -> Jv.call map "closePopup" [| Popup.to_jv popup |]
|
||||
|
|
|
|||
51
src/map.mli
51
src/map.mli
|
|
@ -1,34 +1,55 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t
|
||||
|
||||
module Event : sig
|
||||
(* TODO do this need to be wrapped in Brr.Ev.type' ?*)
|
||||
val click : Ev.Mouse.t Brr.Ev.type'
|
||||
(** [create_on id] creates a map on the <div> with DOM id [id]. To have a
|
||||
functional map you will need to add a tile layer to it. *)
|
||||
val create_on : ?options:Jv.t -> string -> t
|
||||
|
||||
val moveend : Ev.Event.t Brr.Ev.type'
|
||||
|
||||
val zoomend : Ev.Event.t Brr.Ev.type'
|
||||
end
|
||||
|
||||
val create : ?options:Jv.t -> string -> t
|
||||
(** [create_from_div container] creates a map given [container], an instance of
|
||||
a <div> HTML element. To have a functional map you will need to add a tile
|
||||
layer to it. *)
|
||||
val create_from_div : ?options:Jv.t -> Brr.El.t -> t
|
||||
|
||||
(** [invalidate_size map] checks if the map container size changed and updates
|
||||
the map if so *)
|
||||
val invalidate_size : t -> unit
|
||||
|
||||
val set_view : Latlng.t -> ?zoom:int -> t -> unit
|
||||
(** [set_view latlng Some(zoom) map] sets the view of the [map] (geographical
|
||||
center and zoom) *)
|
||||
val set_view : Latlng.t -> zoom:int option -> t -> unit
|
||||
|
||||
(** [fit_world map] sets a map view that mostly contains the whole world with
|
||||
the maximum zoom level possible *)
|
||||
val fit_world : t -> unit
|
||||
|
||||
(** [get_container map] is the HTML element that contains [map] *)
|
||||
val get_container : t -> Brr.El.t
|
||||
|
||||
val on : event:'a Brr.Ev.type' -> handler:('a -> 'b) -> t -> unit
|
||||
(** [on event handler map] add an event listener on [map] for event [event] with
|
||||
handler [handler] *)
|
||||
val on : 'a Event.sub -> ('a Event.t -> unit) -> t -> unit
|
||||
|
||||
(** [get_center map] is the geographical center of the map view *)
|
||||
val get_center : t -> Latlng.t
|
||||
|
||||
(** [get_zoom map] is the current zoom level of the map view *)
|
||||
val get_zoom : t -> int
|
||||
|
||||
val wrapped_latlng : Latlng.t -> t -> Latlng.t
|
||||
(** [wrap_latlng latlng map] returns a new [Latlng.t] where lat and lng has been
|
||||
wrapped according to the map's CRS's wrapLat and wrapLng properties, if they
|
||||
are outside the CRS's bounds. By default this means longitude is wrapped
|
||||
around the dateline so its value is between -180 and +180 degrees *)
|
||||
val wrap_latlng : Latlng.t -> t -> Latlng.t
|
||||
|
||||
val as_target : t -> Brr.Ev.target
|
||||
(** [of_jv jv] is [jv] as {!t} *)
|
||||
val of_jv : Jv.t -> t
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
(** [to_jv o] is [o] as {!Jv.t} *)
|
||||
val to_jv : t -> Jv.t
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
(* [open_popup popup map] opens [popup] on [map]; Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability). *)
|
||||
val open_popup : Popup.t -> t -> unit
|
||||
|
||||
(* [close_popup opt map] if [opt] is [Some popup] closes [popup] else closes previously opened popup *)
|
||||
val close_popup : Popup.t option -> t -> unit
|
||||
|
|
|
|||
|
|
@ -1,4 +1,75 @@
|
|||
(** Marker layers *)
|
||||
include Layer
|
||||
|
||||
let create latlng =
|
||||
of_jv_t @@ Jv.call Global.leaflet "marker" [| Latlng.to_jv_t latlng |]
|
||||
type t = [ `Marker ] Layer.t
|
||||
|
||||
type opt =
|
||||
| Icon of Icon.t
|
||||
| Keyboard of bool
|
||||
| Title of string
|
||||
| Alt of string
|
||||
| Z_index_offset of int
|
||||
| Opacity of float
|
||||
| Rise_on_hover of bool
|
||||
| Rise_offset of int
|
||||
| Pane of string
|
||||
| Shadow_pane of string
|
||||
| Bubbling_mouse_events of bool
|
||||
| Auto_pan_on_focus of bool
|
||||
|
||||
let opt_to_string : opt -> string = function
|
||||
| Icon _ -> "icon"
|
||||
| Keyboard _ -> "keyboard"
|
||||
| Title _ -> "title"
|
||||
| Alt _ -> "alt"
|
||||
| Z_index_offset _ -> "zIndexOffset"
|
||||
| Opacity _ -> "opacity"
|
||||
| Rise_on_hover _ -> "riseOnHover"
|
||||
| Rise_offset _ -> "riseOffset"
|
||||
| Pane _ -> "pane"
|
||||
| Shadow_pane _ -> "shadowPane"
|
||||
| Bubbling_mouse_events _ -> "bubblingMouseEvents"
|
||||
| Auto_pan_on_focus _ -> "autoPanOnFocus"
|
||||
|
||||
let opt_to_jv = function
|
||||
| Icon icon -> Icon.to_jv icon
|
||||
| Keyboard b | Rise_on_hover b | Bubbling_mouse_events b | Auto_pan_on_focus b
|
||||
->
|
||||
Jv.of_bool b
|
||||
| Title s | Alt s | Pane s | Shadow_pane s -> Jv.of_string s
|
||||
| Z_index_offset i | Rise_offset i -> Jv.of_int i
|
||||
| Opacity f -> Jv.of_float f
|
||||
|
||||
let create : Latlng.t -> opt array -> t =
|
||||
fun latlng options ->
|
||||
let l = Array.map (fun o -> (opt_to_string o, opt_to_jv o)) options in
|
||||
let jv_t =
|
||||
Jv.call Global.leaflet "marker" [| Latlng.to_jv latlng; Jv.obj l |]
|
||||
in
|
||||
Marker jv_t
|
||||
|
||||
let get_latlng : t -> Latlng.t = function
|
||||
| Marker marker -> Jv.call marker "getLatLng" [||] |> Latlng.of_jv
|
||||
|
||||
let set_latlng latlng : t -> unit = function
|
||||
| Marker marker ->
|
||||
let (_ : Jv.t) = Jv.call marker "setLatLng" [| Latlng.to_jv latlng |] in
|
||||
()
|
||||
|
||||
let set_z_index_offset z_index : t -> unit = function
|
||||
| Marker marker ->
|
||||
let (_ : Jv.t) = Jv.call marker "setZIndexOffset" [| Jv.of_int z_index |] in
|
||||
()
|
||||
|
||||
let get_icon : t -> Icon.t = function
|
||||
| Marker marker -> Jv.call marker "getIcon" [||] |> Icon.of_jv
|
||||
|
||||
let set_icon icon : t -> unit = function
|
||||
| Marker marker ->
|
||||
let (_ : Jv.t) = Jv.call marker "setIcon" [| Icon.to_jv icon |] in
|
||||
()
|
||||
|
||||
let set_opacity opacity : t -> unit = function
|
||||
| Marker marker ->
|
||||
let (_ : Jv.t) = Jv.call marker "setOpacity" [| Jv.of_int opacity |] in
|
||||
()
|
||||
|
|
|
|||
|
|
@ -1,23 +1,38 @@
|
|||
type t
|
||||
type t = [ `Marker ] Layer.t
|
||||
|
||||
val create : Latlng.t -> t
|
||||
(** type for marker option, used to create marker *)
|
||||
type opt =
|
||||
| Icon of Icon.t
|
||||
| Keyboard of bool
|
||||
| Title of string
|
||||
| Alt of string
|
||||
| Z_index_offset of int
|
||||
| Opacity of float
|
||||
| Rise_on_hover of bool
|
||||
| Rise_offset of int
|
||||
| Pane of string
|
||||
| Shadow_pane of string
|
||||
| Bubbling_mouse_events of bool
|
||||
| Auto_pan_on_focus of bool
|
||||
|
||||
val add_to : Map.t -> t -> unit
|
||||
(** [create latlng options] is a new marker with the same position as [latlng]
|
||||
and with options set to [options] *)
|
||||
val create : Latlng.t -> opt array -> t
|
||||
|
||||
val remove : t -> unit
|
||||
(** Returns the current geographical position of the marker. *)
|
||||
val get_latlng : t -> Latlng.t
|
||||
|
||||
val remove_from : Map.t -> t -> unit
|
||||
(** Changes the marker position to the given point. *)
|
||||
val set_latlng : Latlng.t -> t -> unit
|
||||
|
||||
val bind_popup : Brr.El.t -> t -> unit
|
||||
(** Changes the zIndex offset of the marker. *)
|
||||
val set_z_index_offset : int -> t -> unit
|
||||
|
||||
val unbind_popup : t -> unit
|
||||
(** Returns the current icon used by the marker *)
|
||||
val get_icon : t -> Icon.t
|
||||
|
||||
val open_popup : t -> unit
|
||||
(** Changes the marker icon. *)
|
||||
val set_icon : Icon.t -> t -> unit
|
||||
|
||||
val close_popup : t -> unit
|
||||
|
||||
val get_popup : t -> Popup.t
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
(** Changes the opacity of the marker. *)
|
||||
val set_opacity : int -> t -> unit
|
||||
|
|
|
|||
14
src/point.ml
Normal file
14
src/point.ml
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t =
|
||||
{ x : int
|
||||
; y : int
|
||||
}
|
||||
|
||||
let of_jv point =
|
||||
let x = Jv.get point "x" |> Jv.to_int in
|
||||
let y = Jv.get point "y" |> Jv.to_int in
|
||||
{ x; y }
|
||||
|
||||
let to_jv point =
|
||||
Jv.call Global.leaflet "point" [| Jv.of_int point.x; Jv.of_int point.y |]
|
||||
12
src/point.mli
Normal file
12
src/point.mli
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t =
|
||||
{ x : int
|
||||
; y : int
|
||||
}
|
||||
|
||||
(** [of_jv jv] is [jv] as {!t} *)
|
||||
val of_jv : Jv.t -> t
|
||||
|
||||
(** [to_jv o] is [o] as {!Jv.t} *)
|
||||
val to_jv : t -> Jv.t
|
||||
99
src/popup.ml
99
src/popup.ml
|
|
@ -1,15 +1,98 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t = Jv.t
|
||||
|
||||
let popup = Jv.call Global.leaflet "popup" [||]
|
||||
let set_latlng latlng popup =
|
||||
let (_ : Jv.t) = Jv.call popup "setLatLng" [| Latlng.to_jv latlng |] in
|
||||
()
|
||||
|
||||
let set_latlng latlng =
|
||||
ignore @@ Jv.call popup "setLatLng" [| Latlng.to_jv_t latlng |]
|
||||
let set_content content popup =
|
||||
let (_ : Jv.t) = Jv.call popup "setContent" [| Jv.of_string content |] in
|
||||
()
|
||||
|
||||
let set_content content =
|
||||
ignore @@ Jv.call popup "setContent" [| Jv.of_string content |]
|
||||
let set_content_to_el el popup =
|
||||
let (_ : Jv.t) = Jv.call popup "setContent" [| Brr.El.to_jv el |] in
|
||||
()
|
||||
|
||||
let open_on map = ignore @@ Jv.call popup "openOn" [| Map.to_jv_t map |]
|
||||
let of_jv = Fun.id
|
||||
|
||||
let close map = ignore @@ Jv.call (Map.to_jv_t map) "closePopup" [||]
|
||||
let to_jv = Fun.id
|
||||
|
||||
let of_jv_t = Fun.id
|
||||
type opt =
|
||||
| Pane of string
|
||||
| Offset of Point.t
|
||||
| Max_width of int
|
||||
| Min_width of int
|
||||
| Max_height of int
|
||||
| Auto_pan of bool
|
||||
| Auto_pan_padding_top_left of Point.t
|
||||
| Auto_pan_padding_bottom_right of Point.t
|
||||
| Auto_pan_padding of Point.t
|
||||
| Keep_in_view of bool
|
||||
| Close_button of bool
|
||||
| Auto_close of bool
|
||||
| Close_on_escape_key of bool
|
||||
| Close_on_click of bool
|
||||
| Class_name of string
|
||||
|
||||
let opt_to_string = function
|
||||
| Pane _ -> "pane"
|
||||
| Offset _ -> "offset"
|
||||
| Max_width _ -> "maxWidth"
|
||||
| Min_width _ -> "minWidth"
|
||||
| Max_height _ -> "maxHeight"
|
||||
| Auto_pan _ -> "autoPan"
|
||||
| Auto_pan_padding_top_left _ -> "autoPanPaddingTopLeft"
|
||||
| Auto_pan_padding_bottom_right _ -> "autoPanPaddingBottomRight"
|
||||
| Auto_pan_padding _ -> "autoPanPadding"
|
||||
| Keep_in_view _ -> "keepInView"
|
||||
| Close_button _ -> "closeButton"
|
||||
| Auto_close _ -> "autoClose"
|
||||
| Close_on_escape_key _ -> "closeOnEscapeKey"
|
||||
| Close_on_click _ -> "closeOnClick"
|
||||
| Class_name _ -> "className"
|
||||
|
||||
let opt_to_jv = function
|
||||
| Offset p
|
||||
| Auto_pan_padding_top_left p
|
||||
| Auto_pan_padding_bottom_right p
|
||||
| Auto_pan_padding p ->
|
||||
Point.to_jv p
|
||||
| Max_width i | Min_width i | Max_height i -> Jv.of_int i
|
||||
| Auto_pan b
|
||||
| Keep_in_view b
|
||||
| Close_button b
|
||||
| Auto_close b
|
||||
| Close_on_escape_key b
|
||||
| Close_on_click b ->
|
||||
Jv.of_bool b
|
||||
| Pane s | Class_name s -> Jv.of_string s
|
||||
|
||||
let create ~content ~latlng options =
|
||||
let l = Array.map (fun o -> (opt_to_string o, opt_to_jv o)) options in
|
||||
let popup = Jv.call Global.leaflet "popup" [| Jv.obj l |] in
|
||||
let popup =
|
||||
match latlng with
|
||||
| None -> popup
|
||||
| Some latlng ->
|
||||
set_latlng latlng popup;
|
||||
popup
|
||||
in
|
||||
match content with
|
||||
| None -> popup
|
||||
| Some content ->
|
||||
set_content content popup;
|
||||
popup
|
||||
|
||||
let create_from_el el ~latlng options =
|
||||
let l = Array.map (fun o -> (opt_to_string o, opt_to_jv o)) options in
|
||||
let popup = Jv.call Global.leaflet "popup" [| Jv.obj l |] in
|
||||
let popup =
|
||||
match latlng with
|
||||
| None -> popup
|
||||
| Some latlng ->
|
||||
set_latlng latlng popup;
|
||||
popup
|
||||
in
|
||||
set_content_to_el el popup;
|
||||
popup
|
||||
|
|
|
|||
|
|
@ -1,11 +1,50 @@
|
|||
(* BSD-2-Clause License *)
|
||||
|
||||
type t
|
||||
|
||||
val set_latlng : Latlng.t -> unit
|
||||
(** type for popup option used to create an popup*)
|
||||
type opt =
|
||||
| Pane of string
|
||||
| Offset of Point.t
|
||||
| Max_width of int
|
||||
| Min_width of int
|
||||
| Max_height of int
|
||||
| Auto_pan of bool
|
||||
| Auto_pan_padding_top_left of Point.t
|
||||
| Auto_pan_padding_bottom_right of Point.t
|
||||
| Auto_pan_padding of Point.t
|
||||
| Keep_in_view of bool
|
||||
| Close_button of bool
|
||||
| Auto_close of bool
|
||||
| Close_on_escape_key of bool
|
||||
| Close_on_click of bool
|
||||
| Class_name of string
|
||||
|
||||
val set_content : string -> unit
|
||||
(** [set_latlng latlng popup] sets [popup] position to the given point*)
|
||||
val set_latlng : Latlng.t -> t -> unit
|
||||
|
||||
val open_on : Map.t -> unit
|
||||
(** [set_content s popup] sets [popup] content to [s]*)
|
||||
val set_content : string -> t -> unit
|
||||
|
||||
val close : Map.t -> unit
|
||||
(** [set_content_to_el el s] sets [popup] content to [el]*)
|
||||
val set_content_to_el : Brr.El.t -> t -> unit
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
(** [of_jv jv] is [jv] as {!t} *)
|
||||
val of_jv : Jv.t -> t
|
||||
|
||||
(** [to_jv o] is [o] as {!Jv.t} *)
|
||||
val to_jv : t -> Jv.t
|
||||
|
||||
(** [opt_to_string opt] is [opt] as {!string} *)
|
||||
val opt_to_string : opt -> string
|
||||
|
||||
(** [opt_to_jv opt] is [opt] as {!Jv.t} *)
|
||||
val opt_to_jv : opt -> Jv.t
|
||||
|
||||
(** [create ~content ~latlng options] is a new popup setup with [options],
|
||||
position set to [latlng] and content to [s] *)
|
||||
val create : content:string option -> latlng:Latlng.t option -> opt array -> t
|
||||
|
||||
(** [create_from_el el latlng options] is a new popup setup with [options],
|
||||
position set to [latlng] and content to [el] *)
|
||||
val create_from_el : Brr.El.t -> latlng:Latlng.t option -> opt array -> t
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
include Layer
|
||||
|
||||
let create_osm ?tile_url () =
|
||||
(* see https://wiki.openstreetmap.org/wiki/Tile_servers *)
|
||||
let tile_url =
|
||||
Option.fold ~some:Fun.id
|
||||
~none:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" tile_url
|
||||
in
|
||||
of_jv_t
|
||||
@@ Jv.call Global.leaflet "tileLayer"
|
||||
[| Jv.of_string tile_url
|
||||
; Jv.obj
|
||||
[| ( "attribution"
|
||||
, Jv.of_string
|
||||
"© <a \
|
||||
href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> \
|
||||
contributors" )
|
||||
|]
|
||||
|]
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
type t
|
||||
|
||||
val create_osm : ?tile_url:string -> unit -> t
|
||||
|
||||
val add_to : Map.t -> t -> unit
|
||||
|
||||
val remove : t -> unit
|
||||
|
||||
val remove_from : Map.t -> t -> unit
|
||||
|
||||
val bind_popup : Brr.El.t -> t -> unit
|
||||
|
||||
val unbind_popup : t -> unit
|
||||
|
||||
val open_popup : t -> unit
|
||||
|
||||
val close_popup : t -> unit
|
||||
|
||||
val get_popup : t -> Popup.t
|
||||
|
||||
val of_jv_t : Jv.t -> t
|
||||
|
||||
val to_jv_t : t -> Jv.t
|
||||
BIN
src/vendor/images/layers-2x.png
vendored
Normal file
BIN
src/vendor/images/layers-2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/vendor/images/layers.png
vendored
Normal file
BIN
src/vendor/images/layers.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 696 B |
BIN
src/vendor/images/marker-icon-2x.png
vendored
Normal file
BIN
src/vendor/images/marker-icon-2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
src/vendor/images/marker-icon.png
vendored
Normal file
BIN
src/vendor/images/marker-icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/vendor/images/marker-shadow.png
vendored
Normal file
BIN
src/vendor/images/marker-shadow.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 618 B |
661
src/vendor/leaflet.css
vendored
Normal file
661
src/vendor/leaflet.css
vendored
Normal file
|
|
@ -0,0 +1,661 @@
|
|||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
svg.leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover,
|
||||
.leaflet-bar a:focus {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover,
|
||||
.leaflet-control-attribution a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-attribution-flag {
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
width: 1em;
|
||||
height: 0.6669em;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
white-space: nowrap;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 24px 13px 20px;
|
||||
line-height: 1.3;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
min-height: 1px;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 17px 0;
|
||||
margin: 1.3em 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
pointer-events: auto;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||
color: #757575;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||
color: #585858;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
6
src/vendor/leaflet.js
vendored
Normal file
6
src/vendor/leaflet.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,3 +0,0 @@
|
|||
(test
|
||||
(name test)
|
||||
(modules test))
|
||||
|
|
@ -1 +0,0 @@
|
|||
let () = assert true (* TODO *)
|
||||
Loading…
Add table
Add a link
Reference in a new issue