From 4c5a1230c18295beefea4950373afc1c061a6fe1 Mon Sep 17 00:00:00 2001 From: Candid Dauth Date: Sun, 18 Apr 2021 13:15:06 +0200 Subject: [PATCH] Add more leaflet docs --- docs/src/developers/leaflet/lines.md | 91 +++++++++++++++++++++++++- docs/src/developers/leaflet/markers.md | 77 +++++++++++++++++++++- docs/src/developers/leaflet/route.md | 38 ++++++++++- docs/src/developers/leaflet/search.md | 62 +++++++++++++++++- 4 files changed, 264 insertions(+), 4 deletions(-) diff --git a/docs/src/developers/leaflet/lines.md b/docs/src/developers/leaflet/lines.md index 825d8afe..335d093c 100644 --- a/docs/src/developers/leaflet/lines.md +++ b/docs/src/developers/leaflet/lines.md @@ -1 +1,90 @@ -# Lines \ No newline at end of file +# Lines + +## Show map lines + +`LinesLayer` is a Leaflet layer that will render all the lines on a collaborative map with their appropriate styles (colour and width). To use it, open a connection to a collaborative map using the client and add the layer to the map: + +```javascript +import L from "leaflet"; +import Client from "facilmap-client"; +import { LinesLayer } from "facilmap-leaflet"; + +const map = L.map('map'); +const client = new Client("https://facilmap.org/", "myMapId"); +const linesLayer = new LinesLayer(client).addTo(map); +``` + +`LinesLayer` also has the following features: +* Lines get a tooltip with their name. +* It automatically reacts to changes. When lines are created, changed or deleted, these changes are reflected on the map. `LinesLayer` can also be added before a collaborative map is opened, and will draw the lines as soon as a map is opened. +* It shows/hides the appropriate lines if a [filter](./map#filter) is set. + +## Handle line clicks + +`MarkersLayer` emits a `click` event when a line is clicked. To find out which line was clicked, use `event.layer.line`. + +```javascript +linesLayer.on("click", (event) => { + console.log(event.layer.line); +}); +``` + +You could for example show the line data or highlight the line in reaction to a click. + +## Highlight lines + +Lines can be highlighted, which will remove their opacity and raise them above other elements on the map. The frontend uses this to present a line as selected. + +To highlight a line, use `linesLayer.highlightLine(id)`, `linesLayer.unhighlightLine(id)` or `linesLayer.setHighlightedLines(ids)`. Lines are identified by their ID, which makes it possible to highlight them even before they are actually loaded (they will be highlighted as soon as they are rendered). + +This example will highlight a line on click: + +```javascript +linesLayer.on("click", (event) => { + linesLayer.setHighlightedMarkers([event.layer.line.id]); +}); +``` + +## Draw a line + +Calling `linesLayer.drawLine(lineTemplate)` starts an interaction where the user can draw a line by adding line points through clicks on the map. The user can finish drawing the line by clicking twice on the map, or you can finish the drawing by calling `linesLayer.endDrawLine(true)`, for example in response to clicking a “Finish” button that you show somewhere. + +`lineTemplate` should be a line object with basic styling (`colour` and `width` are defined). Calling `linesLayer.endDrawLine(true)` will finish the operation, while `linesLayer.endDrawLine(false)` will cancel the operation. `linesLayer.drawLine(lineTemplate)` returns a promise that is resolved with the line points (array of objects with a `lat` and `lon` property) when the operation is finished, or with `undefined` when the operation is canceled. + +Here is an example how drawing a line could look: +```javascript +document.getElementById("draw-line-button").addEventListener("click", async () => { + const message = showMessage({ + body: "Click on the map to add line points.", + actions: [ + { text: "Finish", onClick: () => { linesLayer.endDrawLine(true); } }, + { text: "Cancel", onClick: () => { linesLayer.endDrawLine(false); } } + ] + }); + + let routePoints; + try { + routePoints = await linesLayer.drawLine({ colour: "0000ff", width: 7 }); + } catch (error) { + alert(error); + } finally { + message.hide(); + } + + if (routePoints) { + try { + await client.addLine({ typeId: 1, routePoints }); + } catch (error) { + alert(error); + } + } +}); +``` + +## Render a single line + +The code that styles lines on FacilMap has been moved into an external module called [Leaflet.HighlightableLayers](https://github.com/FacilMap/Leaflet.HighlightableLayers). To draw lines that look like FacilMap lines, use that module. + +## Hide a line + +Calling `linesLayer.hideLine(lineId)` hides a line until `linesLayer.unhideLine(lineId)` is called. The frontend uses this function to temporarily make a line draggable by calling [client.lineToRoute()](../client/methods#linetoroute-data) to convert the line to a route and hiding the line until the dragging has finished. \ No newline at end of file diff --git a/docs/src/developers/leaflet/markers.md b/docs/src/developers/leaflet/markers.md index c0cd8b09..2ba74126 100644 --- a/docs/src/developers/leaflet/markers.md +++ b/docs/src/developers/leaflet/markers.md @@ -1 +1,76 @@ -# Markers \ No newline at end of file +# Markers + +## Show map markers + +`MarkersLayer` is a Leaflet layer that will render all the markers on a collaborative map with their appropriate styles (colour, size, icon and shape). To use it, open a connection to a collaborative map using the client and add the layer to the map: + +```javascript +import L from "leaflet"; +import Client from "facilmap-client"; +import { MarkersLayer } from "facilmap-leaflet"; + +const map = L.map('map'); +const client = new Client("https://facilmap.org/", "myMapId"); +const markersLayer = new MarkersLayer(client).addTo(map); +``` + +`MarkersLayer` also has the following features: +* It clusters markers if this has been enabled in the map settings. +* Markers get a tooltip with their name. +* It automatically reacts to changes. When markers are created, changed or deleted, these changes are reflected on the map. `MarkersLayer` can also be added before a collaborative map is opened, and will draw the markers as soon as a map is opened. +* It shows/hides the appropriate markers if a [filter](./map#filter) is set. + +## Handle marker clicks + +`MarkersLayer` emits a `click` event when a marker is clicked. To find out which marker was clicked, use `event.layer.marker`. + +```javascript +markersLayer.on("click", (event) => { + console.log(event.layer.marker); +}); +``` + +You could for example show the marker data or highlight the marker in reaction to a click. + +## Highlight markers + +Markers can be highlighted, which will increase their border width, remove their opacity and raise them above other elements on the map. The frontend uses this to present a marker as selected. + +To highlight a marker, use `markersLayer.highlightMarker(id)`, `markersLayer.unhighlightMarker(id)` or `markersLayer.setHighlightedMarkers(ids)`. Markers are identified by their ID, which makes it possible to highlight them even before they are actually loaded (they will be highlighted as soon as they are rendered). + +This example will highlight a marker on click: + +```javascript +markersLayer.on("click", (event) => { + markersLayer.setHighlightedMarkers([event.layer.marker.id]); +}); +``` + +## Show a particular marker + +If you want to make sure that a marker with a particular ID is shown (regardless of whether it is in the current bbox or not), call `markersLayer.showMarker(id)`. This will load the marker from the server if it is not loaded yet. Calling `markersLayer.showMarker(id, true)` will load the marker and fly to it. + +## Render a single marker + +`MarkerLayer` (in singular, as opposed to `MarkersLayer`) makes it possible to render an individual marker object with its appropriate style. It does not automatically update when the marker changes and can also be used for markers that are not saved on the map. + +`MarkerLayer` is based on regular [Leaflet markers](https://leafletjs.com/reference.html#marker), but accepts the following additional options: +* `marker`: A marker object that the marker style will be based on. Only the properties relevant for the style (`colour`, `size`, `symbol` and `shape`) need to be set. +* `highlight`: If this is `true`, the marker will be shown with a thicker border. +* `raised`: If this is `true`, the marker will be rendered above other map objects. + +```javascript +import L from "leaflet"; +import { MarkerLayer } from "facilmap-leaflet"; + +const map = L.map('map'); +new MarkerLayer([52.5295, 13.3840], { + marker: { colour: "00ff00", size: 40, symbol: "alert", shape: "pentagon" } +}).addTo(map); +``` + +## Lock a marker + +Locking a marker will disable any position and filter updates for it. It will be shown regardless of whether a filter expression applies to it or not, and updates to its position on the collaborative map will be ignored, although style updates are still applied. The frontend uses this function for its “Move marker” feature. Users wouldn’t want the marker to jump to another place or to disappear while they are dragging it. + +To lock a marker, call `markersLayer.lockMarker(markerId)`. To unlock it again, call `markersLayer.unlockMarker(markerId)`. \ No newline at end of file diff --git a/docs/src/developers/leaflet/route.md b/docs/src/developers/leaflet/route.md index 8bbd4196..b0235483 100644 --- a/docs/src/developers/leaflet/route.md +++ b/docs/src/developers/leaflet/route.md @@ -1 +1,37 @@ -# Route \ No newline at end of file +# Route + +Routes in FacilMap are temporarily stored on the server in the scope of one particular client connection, unrelated to any collaborative map that is opened. This makes it possible that only the track points appropriate for the current bounding box and zoom level have to be received by the client, rather than the whole route in all detail. Multiple routes can be active at the same time by specifying a custom `routeId` when calling [setRoute()](../client/methods#setroute-data). + +## Show a route + +`RouteLayer` renders a route with one particular `routeId` on the map. As long as no route with that `routeId` is active, no route is shown, and as soon as a route is received, it is automatically rendered. An example usage pattern would be that you have one routing form that uses a fixed `routeId`, which would control the active route using [setRoute()](../client/methods#setroute-data) and [clearRoute()](../client/methods#clearroute-data), and there would be one `RouteLayer` for that `routeId` constantly present on the map which would always show the current state of the route. + +The `RouteLayer` constructor accepts the following arguments: +* A client instance +* A `routeId` (string or undefined) +* Layer options (any [Leaflet.HighlightableLayers](https://github.com/FacilMap/Leaflet.HighlightableLayers) can be specified) + +Example usage: +```javascript +import L from "leaflet"; +import Client from "facilmap-client"; +import { RouteLayer } from "facilmap-leaflet"; + +const map = L.map('map'); +const client = new Client("https://facilmap.org/", "myMapId"); +const routeLayer = new RouteLayer(client, "routeForm", { raised: true }).addTo(map); +``` + +## Make a route draggable + +Most of the logic to make routes draggable has been moved into the external module [Leaflet.DraggableLines](https://github.com/FacilMap/Leaflet.DraggableLines). + +`RouteDragHandler` is an extended version of `DraggableLines` that automatically updates the route points when the route is dragged, causing it to be recalculated. + +Example usage: +```javascript +import { RouteDragHandler } from "facilmap-leaflet"; + +const routeDragHandler = new RouteDragHandler(map, client).enable(); +routeDragHandler.enableForLayer(routeLayer); +``` \ No newline at end of file diff --git a/docs/src/developers/leaflet/search.md b/docs/src/developers/leaflet/search.md index 6aaea9fe..adf5860e 100644 --- a/docs/src/developers/leaflet/search.md +++ b/docs/src/developers/leaflet/search.md @@ -1 +1,61 @@ -# Search \ No newline at end of file +# Search + +## Show search results + +`SearchResultsLayer` renders search results as markers, lines and polygons on the map. The constructor accepts the following arguments: +* `results`: An array of search results as returned by [client.find()](../client/methods#find-data). You can also leave this `undefined` and add results later using `setResults()`. +* `options`: An optional object containing the following properties: + * `markerColour`: A 6-digit colour to use for search result markers, defaults to `000000` + * `markerSize`: The height of search result markers in pixels, defaults to `35` + * `markerShape`: The shape of search result markers, defaults to `drop` + * `pathOptions`: [Path options](https://leafletjs.com/reference.html#path-option) for lines and polygons. + +Note that the marker symbol is determined by the type of result. + +Example usage: +```javascript +import L from "leaflet"; +import Client from "facilmap-client"; +import { SearchResultsLayer } from "facilmap-leaflet"; + +const map = L.map('map'); +const client = new Client("https://facilmap.org/"); +const resultLayer = new SearchResultsLayer().addTo(map); + +document.getElementById("search-form").addEventListener("submit", async () => { + const query = document.getElementById("search-input").value; + if (query.trim() != "") { + try { + resultLayer.setResults(await client.find({ query })); + } catch (err) { + alert(err); + } + } else { + resultsLayer.setResults([]); + } +}); +``` + +## Handle result click + +`SearchResultsLayer` fires a `click` event when a result is clicked. To determine which result was clicked, use `event.layer._fmSearchResult`. + +Example: +```javascript +resultsLayer.on("click", (event) => { + alert(event.layer._fmSearchResult.display_name); +}); +``` + +## Highlight results + +Using `resultsLayer.highlightResult(result)`, `resultsLayer.unhighlightResult(result)` and `resultsLayer.setHighlightedResults(results)`, you can highlight some search results, causing them to be rendered with an increased outline, no opacity and above other map objects. The frontend uses this to present them as selected. + +A single search result might consist of multiple geometries, for example a marker and a polygon. Highlighting a search result will highlight all those geometries. + +In this example, a search result is highlighted when clicked: +```javascript +resultsLayer.on("click", (event) => { + resultsLayer.setHighlightedResults([event.layer._fmSearchResult]); +}); +``` \ No newline at end of file