diff --git a/src/dune b/src/dune
index e7f3daf..8f28969 100644
--- a/src/dune
+++ b/src/dune
@@ -1,7 +1,7 @@
(library
(name leaflet)
(public_name leaflet)
- (modules ev latlng geojson_layer tile_layer popup marker map global)
+ (modules ev latlng geojson_layer tile_layer popup marker map global layer)
(libraries brr js_of_ocaml)
(js_of_ocaml
(javascript_files leaflet.js)))
diff --git a/src/geojson_layer.ml b/src/geojson_layer.ml
index 66ed14a..c5c113d 100644
--- a/src/geojson_layer.ml
+++ b/src/geojson_layer.ml
@@ -1,7 +1,4 @@
-(*TODO merge with TileLayer*)
-type t = Jv.t
+include Layer
let create ?(options = Jv.null) geojson =
- Jv.call Global.leaflet "geoJSON" [| geojson; options |]
-
-let add_to layer map = ignore @@ Jv.call layer "addTo" [| Map.to_jv_t map |]
+ of_jv_t @@ Jv.call Global.leaflet "geoJSON" [| geojson; options |]
diff --git a/src/geojson_layer.mli b/src/geojson_layer.mli
index 12bb980..e8c4660 100644
--- a/src/geojson_layer.mli
+++ b/src/geojson_layer.mli
@@ -2,4 +2,22 @@ type t
val create : ?options:Jv.t -> Jv.t -> t
-val add_to : t -> Map.t -> unit
+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
diff --git a/src/layer.ml b/src/layer.ml
new file mode 100644
index 0000000..d0c8b62
--- /dev/null
+++ b/src/layer.ml
@@ -0,0 +1,23 @@
+type t = Jv.t
+
+let add_to map layer = ignore @@ Jv.call layer "addTo" [| Map.to_jv_t map |]
+
+let remove layer = ignore @@ Jv.call layer "remove" [||]
+
+let remove_from map layer =
+ ignore @@ Jv.call layer "removeFrom" [| Map.to_jv_t map |]
+
+let bind_popup el layer =
+ ignore @@ Jv.call layer "bindPopup" [| Brr.El.to_jv el |]
+
+let unbind_popup layer = ignore @@ Jv.call layer "unbindPopup" [||]
+
+let open_popup layer = ignore @@ Jv.call layer "openPopup" [||]
+
+let close_popup layer = ignore @@ Jv.call layer "closePopup" [||]
+
+let get_popup layer = Popup.of_jv_t @@ Jv.call layer "getPopup" [||]
+
+let of_jv_t = Fun.id
+
+let to_jv_t = Fun.id
diff --git a/src/layer.mli b/src/layer.mli
new file mode 100644
index 0000000..98fe10c
--- /dev/null
+++ b/src/layer.mli
@@ -0,0 +1,21 @@
+type 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
diff --git a/src/marker.ml b/src/marker.ml
index cfcd0b3..44925a1 100644
--- a/src/marker.ml
+++ b/src/marker.ml
@@ -1,11 +1,4 @@
-type t = Jv.t
+include Layer
-let create latlng = Jv.call Global.leaflet "marker" [| Latlng.to_jv_t latlng |]
-
-let add_to marker map = ignore @@ Jv.call marker "addTo" [| Map.to_jv_t map |]
-
-let bind_popup el marker =
- ignore @@ Jv.call marker "bindPopup" [| Brr.El.to_jv el |];
- marker
-
-let open_popup marker = ignore @@ Jv.call marker "openPopup" [||]
+let create latlng =
+ of_jv_t @@ Jv.call Global.leaflet "marker" [| Latlng.to_jv_t latlng |]
diff --git a/src/marker.mli b/src/marker.mli
index 3bf1691..ab77fc5 100644
--- a/src/marker.mli
+++ b/src/marker.mli
@@ -2,10 +2,22 @@ type t
val create : Latlng.t -> t
-val add_to : t -> Map.t -> unit
+val add_to : Map.t -> t -> unit
-(** {2 Popup methods} *)
+val remove : t -> unit
-val bind_popup : Brr.El.t -> t -> t
+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
diff --git a/src/popup.ml b/src/popup.ml
index 9a268db..bc0febf 100644
--- a/src/popup.ml
+++ b/src/popup.ml
@@ -1,3 +1,5 @@
+type t = Jv.t
+
let popup = Jv.call Global.leaflet "popup" [||]
let set_latlng latlng =
@@ -9,3 +11,5 @@ let set_content content =
let open_on map = ignore @@ Jv.call popup "openOn" [| Map.to_jv_t map |]
let close map = ignore @@ Jv.call (Map.to_jv_t map) "closePopup" [||]
+
+let of_jv_t = Fun.id
diff --git a/src/popup.mli b/src/popup.mli
index cda85f6..5ca939b 100644
--- a/src/popup.mli
+++ b/src/popup.mli
@@ -1,3 +1,5 @@
+type t
+
val set_latlng : Latlng.t -> unit
val set_content : string -> unit
@@ -5,3 +7,5 @@ val set_content : string -> unit
val open_on : Map.t -> unit
val close : Map.t -> unit
+
+val of_jv_t : Jv.t -> t
diff --git a/src/tile_layer.ml b/src/tile_layer.ml
index 137eb64..1dae48c 100644
--- a/src/tile_layer.ml
+++ b/src/tile_layer.ml
@@ -1,4 +1,4 @@
-type t = Jv.t
+include Layer
let create_osm ?tile_url () =
(* see https://wiki.openstreetmap.org/wiki/Tile_servers *)
@@ -6,16 +6,14 @@ let create_osm ?tile_url () =
Option.fold ~some:Fun.id
~none:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" tile_url
in
- Jv.call Global.leaflet "tileLayer"
- [| Jv.of_string tile_url
- ; Jv.obj
- [| ( "attribution"
- , Jv.of_string
- "© OpenStreetMap \
- contributors" )
- |]
- |]
-
-let add_to tile_layer map =
- ignore @@ Jv.call tile_layer "addTo" [| Map.to_jv_t map |]
+ of_jv_t
+ @@ Jv.call Global.leaflet "tileLayer"
+ [| Jv.of_string tile_url
+ ; Jv.obj
+ [| ( "attribution"
+ , Jv.of_string
+ "© OpenStreetMap \
+ contributors" )
+ |]
+ |]
diff --git a/src/tile_layer.mli b/src/tile_layer.mli
index 4fffaa2..b1834b5 100644
--- a/src/tile_layer.mli
+++ b/src/tile_layer.mli
@@ -2,4 +2,22 @@ type t
val create_osm : ?tile_url:string -> unit -> t
-val add_to : t -> Map.t -> unit
+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