Compare commits

...

44 commits

Author SHA1 Message Date
db37034a70 migrate to forge.kumikode.org 2026-03-19 21:49:00 +01:00
e16618f49e version 0.2 2026-03-19 21:49:00 +01:00
25be80020b don't generate opam file with dune 2026-03-19 21:49:00 +01:00
0756aef64b better readme; rm empty test/ 2026-03-19 21:49:00 +01:00
7ab765a333 basic example with tiny_httpd 2026-03-19 21:49:00 +01:00
107c27db95 ocamlformat 2026-03-19 21:49:00 +01:00
00dc9e6851 Map.on: make handler type be (.. -> unit) 2026-03-19 21:49:00 +01:00
ca369c219e use dune-site 2026-03-19 21:49:00 +01:00
8ade976f6c update leaflet.js 2026-03-19 21:49:00 +01:00
ce61a7a77a create_geojson need a json object 2026-03-19 21:49:00 +01:00
7fd1ca44e4 ocamlformat 2026-03-19 21:49:00 +01:00
f0a168c8e9 close_popup: rm label 2026-03-19 21:49:00 +01:00
a44f13085d add cirecle marker 2026-03-19 21:49:00 +01:00
16e5fe0b2e list -> array 2026-03-19 21:49:00 +01:00
3d19bc3f40 add polyline layer 2026-03-19 21:49:00 +01:00
076e3dd279 add more options to tile_layer 2026-03-19 21:49:00 +01:00
71cdf5f97c cleanup Marker 2026-03-19 21:49:00 +01:00
bbe481c064 add tile_layer_opt; untested 2026-03-19 21:49:00 +01:00
b2c78c1e5d add Icon.set_default_image_path 2026-03-19 21:49:00 +01:00
a8266ae615 move marker to separate module 2026-03-19 21:49:00 +01:00
1118889253 -> Latlng.create ~lat ~lng 2026-03-19 21:49:00 +01:00
b9c6864ef1 small popup change 2026-03-19 21:49:00 +01:00
1e581ef172 update ocamlformat 2026-03-19 21:49:00 +01:00
fd38f85f72 fix doc 2026-03-19 21:49:00 +01:00
0c36e1336d more marker function 2026-03-19 21:49:00 +01:00
ce8dcba87a add Icon.create_div 2026-03-19 21:49:00 +01:00
7effdcc577 better popups 2026-03-19 21:49:00 +01:00
23ea827e40 better Layer.bind_popup and add Map.open/close_popup 2026-03-19 21:49:00 +01:00
2affa8b5fa fix Point_to_layer 2026-03-19 21:49:00 +01:00
ede9b2076d add popup options 2026-03-19 21:49:00 +01:00
a438e54f42 add geojson options 2026-03-19 21:49:00 +01:00
fbcb87f0d8 add marker options 2026-03-19 21:49:00 +01:00
c3766414c3 add icon 2026-03-19 21:49:00 +01:00
5fecae013c add of_jv, on, ?options for bind_popup 2026-03-19 21:49:00 +01:00
10aaf21209 add js_of_ocaml to package dependency 2026-03-19 21:49:00 +01:00
83527f5cae change map creation 2026-03-19 21:49:00 +01:00
06c614d2c5 add usage to readme 2026-03-19 21:49:00 +01:00
38c0d5ef53 add documentation, remove Map.as_target 2026-03-19 21:49:00 +01:00
68ee03bead make Map.create take Brr.El 2026-03-19 21:49:00 +01:00
0370fb97a2 add example 2026-03-19 21:49:00 +01:00
f0435c549b add point 2026-03-19 21:49:00 +01:00
d6195f00e9 license 2026-03-19 21:48:58 +01:00
dbfbaeda60 use gadts for layer, clean code 2022-04-09 22:27:06 +02:00
2a760bc98d use gadts for event, clean repo 2022-04-09 14:01:58 +02:00
48 changed files with 1767 additions and 358 deletions

View file

@ -1,4 +1,4 @@
version=0.21.0 version=0.28.1
assignment-operator=end-line assignment-operator=end-line
break-cases=fit break-cases=fit
break-fun-decl=wrap break-fun-decl=wrap

View file

@ -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.

View file

@ -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.

View file

@ -1,6 +1,6 @@
# leaflet # leaflet
[leaflet] is an [OCaml] executable/library to TODO. `leaflet` is an [OCaml] bindings library for the [Leaflet] JavaScript library (v1.9.4).
## Installation ## 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. If you can't or don't want to use `opam`, consult the [opam file] for build instructions.
## Quickstart ## Usage
```ocaml The library use `dune-site` to install [leaflet's files] (CSS and images).
let () = Format.printf "TODO@."
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 ## About
This library started off from the code of a [NGI0 funded project]
- [LICENSE] - [LICENSE]
- [CHANGELOG] - [CHANGELOG]
[CHANGELOG]: ./CHANGES.md [CHANGELOG]: ./CHANGES.md
[example]: ./example
[LICENSE]: ./LICENSE.md [LICENSE]: ./LICENSE.md
[opam file]: ./leaflet.opam [opam file]: ./leaflet.opam
[test suite]: ./test
[documentation]: TODO/leaflet
[how to install opam]: https://opam.ocaml.org/doc/Install.html [how to install opam]: https://opam.ocaml.org/doc/Install.html
[OCaml]: https://ocaml.org [OCaml]: https://ocaml.org
[opam]: https://opam.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

View file

@ -1,17 +1,7 @@
{0 leaflet} {0 Leaflet}
{{:https://TODO/leaflet} leaflet} is an {{:https://ocaml.org} OCaml} library/executable to TODO. Leaflet is an [OCaml] bindings library for the {{:https://leafletjs.com} Leaflet} JavaScript library.
{1:api API}
{!modules: {!modules:
Leaflet Leaflet
} }
{1:private_api Private API}
You shouldn't have to use any of these modules, they're used internally only.
{!modules:
TODO
}

View file

@ -1,33 +1,20 @@
(lang dune 2.9) (lang dune 2.9)
(using dune_site 0.1)
(implicit_transitive_deps false) ;uncomment when fixed: https://github.com/ocaml/dune/issues/9661
;(implicit_transitive_deps false)
(name leaflet) (name leaflet)
(license ISC) (generate_opam_files false)
(authors "TODO")
(maintainers "TODO")
(source
(uri TODO/leaflet))
(homepage TODO/leaflet)
(bug_reports TODO/leaflet)
(documentation TODO/leaflet)
(generate_opam_files true)
(package (package
(name leaflet) (name leaflet)
(synopsis "OCaml library/executable to TODO")
(description
"leaflet is an OCaml library/executable to TODO.")
(tags
(leaflet TODO TODO TODO TODO))
(depends (depends
(ocaml (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
View file

View file

@ -1,3 +1,25 @@
(executable (executable
(name main) (name script)
(modules main)) (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
View 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>

View file

@ -1 +0,0 @@
let () = Format.printf "TODO@."

16
example/script.ml Normal file
View 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
View 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

View file

@ -1,17 +1,26 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0" opam-version: "2.0"
synopsis: "OCaml library/executable to TODO" name: "leaflet"
description: "leaflet is an OCaml library/executable to TODO." version: "0.2"
maintainer: ["TODO"] synopsis: "Bindings for the Leaflet JavaScript library"
authors: ["TODO"] description:
license: "ISC" "leaflet is an OCaml bindings library for the Leaflet JavaScript library."
tags: ["leaflet" "TODO" "TODO" "TODO" "TODO"] maintainer: ["swrup <swrup@protonmail.com>"]
homepage: "TODO/leaflet" authors: [
doc: "TODO/leaflet" "pukkamustard <pukkamustard@posteo.net>"
bug-reports: "TODO/leaflet" "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: [ depends: [
"dune" {>= "2.9"} "dune" {>= "2.9"}
"ocaml" {>= "4.08"} "ocaml" {>= "4.08"}
"brr"
"js_of_ocaml"
"dune-site"
"tiny_httpd" {with-test}
"odoc" {with-doc} "odoc" {with-doc}
] ]
build: [ build: [
@ -30,4 +39,4 @@ build: [
] ]
["dune" "install" "-p" name "--create-install-files" name] ["dune" "install" "-p" name "--create-install-files" name]
] ]
dev-repo: "TODO/leaflet" dev-repo: "git+https://forge.kumikode.org/kumikode/leaflet.git"

View file

@ -1,7 +1,25 @@
(library (library
(name leaflet)
(public_name leaflet) (public_name leaflet)
(modules ev latlng geojson_layer tile_layer popup marker map global layer) (modules event global latlng layer map marker popup point icon)
(libraries brr js_of_ocaml) (private_modules global)
(libraries brr)
(js_of_ocaml (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)))

View file

@ -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 ()

View file

@ -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
View 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
View 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

View file

@ -1,4 +0,0 @@
include Layer
let create ?(options = Jv.null) geojson =
of_jv_t @@ Jv.call Global.leaflet "geoJSON" [| geojson; options |]

View file

@ -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

View file

@ -1,3 +1,5 @@
(* BSD-2-Clause License *)
let leaflet = let leaflet =
match Jv.(find global "L") with match Jv.(find global "L") with
| Some l -> l | Some l -> l

74
src/icon.ml Normal file
View 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
View 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

View file

@ -1,6 +1,8 @@
(* BSD-2-Clause License *)
type t = Jv.t 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 |] Jv.call Global.leaflet "latLng" [| Jv.of_float lat; Jv.of_float lng |]
let lat latlng = Jv.get latlng "lat" |> Jv.to_float 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 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

View file

@ -1,13 +1,23 @@
(* BSD-2-Clause License *)
type t 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 val lat : t -> float
(** [lng o] is the longitude of [o] *)
val lng : t -> float 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 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

View file

@ -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 = (** Basic layers *)
ignore @@ Jv.call layer "removeFrom" [| Map.to_jv_t map |]
let bind_popup el layer = let add_to : type kind. Map.t -> kind t -> unit =
ignore @@ Jv.call layer "bindPopup" [| Brr.El.to_jv el |] 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 =
"&copy; <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

View file

@ -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

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: 2010-2021 Vladimir Agafonkin
SPDX-License-Identifier: BSD-2-Clause

View file

@ -1,46 +1,58 @@
(* BSD-2-Clause License *)
type t = Jv.t type t = Jv.t
module Event = struct let of_jv = Fun.id
let to_brr s = s |> Jstr.v |> Brr.Ev.Type.create
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" let create_from_div ?(options = Jv.null) container =
end 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 = let get_container map = Jv.call (to_jv map) "getContainer" [||] |> Brr.El.of_jv
Jv.call Global.leaflet "map" [| Jv.of_string container_id; options |]
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 fit_world map = ignore @@ Jv.call map "fitWorld" [||] let (_ : Jv.t) =
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 match zoom with
| None -> Jv.call map "setView" [| latlng |] | None -> Jv.call map "setView" [| latlng |]
| Some zoom -> Jv.call map "setView" [| latlng; Jv.of_int zoom |] | Some zoom -> Jv.call map "setView" [| latlng; Jv.of_int zoom |]
in
()
let as_target map = Brr.Ev.target_of_jv map 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 on ~event ~handler map = let get_center map = Latlng.of_jv @@ Jv.call map "getCenter" [||]
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_zoom map = Jv.call map "getZoom" [||] |> Jv.to_int let get_zoom map = Jv.call map "getZoom" [||] |> Jv.to_int
let wrapped_latlng latlng map = let wrap_latlng latlng map =
Latlng.of_jv_t @@ Jv.call map "wrapLatLng" [| Latlng.to_jv_t latlng |] 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 |]

View file

@ -1,34 +1,55 @@
(* BSD-2-Clause License *)
type t type t
module Event : sig (** [create_on id] creates a map on the <div> with DOM id [id]. To have a
(* TODO do this need to be wrapped in Brr.Ev.type' ?*) functional map you will need to add a tile layer to it. *)
val click : Ev.Mouse.t Brr.Ev.type' val create_on : ?options:Jv.t -> string -> t
val moveend : Ev.Event.t Brr.Ev.type' (** [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
val zoomend : Ev.Event.t Brr.Ev.type' layer to it. *)
end val create_from_div : ?options:Jv.t -> Brr.El.t -> t
val create : ?options:Jv.t -> string -> t
(** [invalidate_size map] checks if the map container size changed and updates
the map if so *)
val invalidate_size : t -> unit 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 val fit_world : t -> unit
(** [get_container map] is the HTML element that contains [map] *)
val get_container : t -> Brr.El.t 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 val get_center : t -> Latlng.t
(** [get_zoom map] is the current zoom level of the map view *)
val get_zoom : t -> int 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

View file

@ -1,4 +1,75 @@
(** Marker layers *)
include Layer include Layer
let create latlng = type t = [ `Marker ] Layer.t
of_jv_t @@ Jv.call Global.leaflet "marker" [| Latlng.to_jv_t latlng |]
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
()

View file

@ -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 (** Changes the opacity of the marker. *)
val set_opacity : int -> t -> unit
val get_popup : t -> Popup.t
val of_jv_t : Jv.t -> t
val to_jv_t : t -> Jv.t

14
src/point.ml Normal file
View 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
View 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

View file

@ -1,15 +1,98 @@
(* BSD-2-Clause License *)
type t = Jv.t 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 = let set_content content popup =
ignore @@ Jv.call popup "setLatLng" [| Latlng.to_jv_t latlng |] let (_ : Jv.t) = Jv.call popup "setContent" [| Jv.of_string content |] in
()
let set_content content = let set_content_to_el el popup =
ignore @@ Jv.call popup "setContent" [| Jv.of_string content |] 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

View file

@ -1,11 +1,50 @@
(* BSD-2-Clause License *)
type t 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

View file

@ -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
"&copy; <a \
href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> \
contributors" )
|]
|]

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 618 B

661
src/vendor/leaflet.css vendored Normal file
View 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

File diff suppressed because one or more lines are too long

View file

@ -1,3 +0,0 @@
(test
(name test)
(modules test))

View file

@ -1 +0,0 @@
let () = assert true (* TODO *)