Start documenting facilmap-leaflet

pull/149/head
Candid Dauth 2021-04-17 19:46:01 +02:00
rodzic 5c739f66e4
commit 0a780f45c3
19 zmienionych plików z 261 dodań i 9 usunięć

Wyświetl plik

@ -103,6 +103,25 @@ module.exports = {
"client/advanced"
]
},
{
title: "Leaflet components",
collapsable: false,
children: [
"leaflet/",
"leaflet/bbox",
"leaflet/layers",
"leaflet/markers",
"leaflet/lines",
"leaflet/route",
"leaflet/search",
"leaflet/icons",
"leaflet/hash",
"leaflet/initial-view",
"leaflet/views",
"leaflet/click-listener",
"leaflet/map"
]
},
{
title: 'Development',
collapsable: false,

Wyświetl plik

@ -1,6 +1,25 @@
# Overview
## Quick links
* [Embed FacilMap](./embed) into any website using an iframe.
* Run your own [FacilMap server](./server/).
* Use the [FacilMap client](./client/) to programmatically access and modify data on a collaborative map.
* Read about the [dev setup](./development/dev-setup) to start contributing to the FacilMap code.
* Read about the [dev setup](./development/dev-setup) to start contributing to the FacilMap code.
## Structural overview
FacilMap consists of several layers:
* The **Server** is a Node.js app that stores the data of collaborative maps in a database and runs a [socket.io](https://socket.io/) server to access and modify those maps. It also includes a HTTP server that serves the frontend and the map exports.
* The **Client** is a JavaScript library that provides methods to access the data on collaborative maps by sending requests to the socket.io server.
* The **Leaflet components** is a JavaScript library that provides classes to dynamically show the data received by the Client on a [Leaflet](https://leafletjs.com/) map.
* The **Frontend** is a JavaScript app that provides a complete UI written in [Vue.js](https://vuejs.org/) to create, access and modify collaborative maps. It uses the Client to access those maps and the Leaflet components to render them on a map.
FacilMap is completely written in [TypeScript](https://www.typescriptlang.org/). The code base is split into several NPM modules, each of which can be used independently (although some depend on some others):
* [facilmap-types](https://www.npmjs.com/package/facilmap-types) provides common TypeScript types for map objects and the socket communication and is used by all other modules.
* [facilmap-client](https://www.npmjs.com/package/facilmap-client) contains the [FacilMap client](./client/).
* [facilmap-utils](https://www.npmjs.com/package/facilmap-utils) contains helper methods that are used by facilmap-leaflet, facilmap-frontend and facilmap-server, so they can run both in the browser and in Node.js.
* [facilmap-leaflet](https://www.npmjs.com/package/facilmap-leaflet) contains the Leaflet components.
* [facilmap-frontend](https://www.npmjs.com/package/facilmap-frontend) contains the Frontend.
* [facilmap-server](https://www.npmjs.com/package/facilmap-server) contains the [Server](./server/).

Wyświetl plik

@ -0,0 +1,54 @@
# Overview
The Leaflet components of FacilMap are classes that you can use to show FacilMap data on a [Leaflet](https://leafletjs.com/) map.
The Leaflet components are only useful in combination with a [FacilMap client](../client/) instance. Most components either require an object created by the client as an argument, or require the client instance itself and render the available map data automatically.
## Components
* [BboxHandler](./bbox) automatically calls [updateBbox()](../client/methods#updatebbox-bbox) when the position of the map changes.
* [Layers](./layers) provides the layers that FacilMap offers by default and helpers to show them.
* [Markers](./markers) shows the markers of a collaborative map.
* [Lines](./lines) shows the lines of a collaborative map.
* [Route](./route) allows showing a calculated route on the map.
* [Search](./search) renders search results.
* [Icons](./icons) provides methods to draw marker icons and shapes.
* [HashHandler](./hash) hooks up the location hash to the current map view.
* [Initial view](./initial-view) uses geoip or the default view of the opened collaborative map to set the initial view of a map.
* [Views](./views) allow opening or creating a saved view.
* [Click listener](./click-listener) is a helper to ask the user to click somewhere on the map.
* [Map extensions](./map) add some additional methods and events to Leaflet maps, for example to apply a filter expression to control which markers/lines are shown.
## Setup
The Leaflet components are published on npm as [facilmap-leaflet](https://www.npmjs.com/package/facilmap-leaflet). The recommended way to use them is to install the package using npm or yarn:
```bash
npm install -S facilmap-leaflet
```
```javascript
import L from "leaflet";
import Client from "facilmap-client";
import { BboxHandler } from "facilmap-leaflet";
const map = L.map('map');
const client = new Client("https://facilmap.org/");
new BboxHandler(map, client).enable();
```
However, a build to use the components directly in the browser is also available. The build contains all the dependencies except Leaflet, including the FacilMap client. The components are available in the global `L.FacilMap` object.
```html
<script src="https://unpkg.com/leaflet@1"></script>
<script src="https://unpkg.com/facilmap-leaflet@3/dist/facilmap-leaflet.full.js"></script>
<script>
const map = L.map('map');
const client = new FacilMap.Client("https://facilmap.org/");
new L.FacilMap.BboxHandler(map, client).enable();
</script>
```
## Example
An example that shows all the Leaflet components in actions can be found in [example.html](https://github.com/FacilMap/facilmap/blob/master/leaflet/example.html) ([demo](https://unpkg.com/facilmap-leaflet/example.html)).

Wyświetl plik

@ -0,0 +1,32 @@
# BboxHandler
The FacilMap client needs to tell the current bounding box and zoom level of the map to the server in order to receive the following information:
* If a collaborative map is open, the markers in the specified bounding box
* If a collaborative map is open, the line points in the specified bounding box (simplified for the specified zoom level)
* If a calculated route is active, the route points in the specified bounding box (simplified for the specified zoom level).
BboxHandler automatically calls [updateBbox()](../client/methods#updatebbox-bbox) whenever the position of the map changes, either because the user panned the map or because it was changed programmatically.
## Usage
BboxHandler extends [L.Handler](https://leafletjs.com/reference.html#handler). To use it, pass the map and client objects to the constructor and enable the handler.
```javascript
import { map } from "leaflet";
import Client from "facilmap-client";
import { BboxHandler } from "facilmap-leaflet";
const map = map('map');
const client = new Client("https://facilmap.org/");
new BboxHandler(map, client).enable();
```
## Technical details
The bbox is only sent to the server if one of the following conditions are met (because only in these conditions the bbox is relevant for the server):
* A collaborative map is opened
* A route is active
The bbox will be sent as soon as one of these conditions is fulfilled, and each time the position of the map is changed. The bbox is updated when Leaflet fires a [`moveend`](https://leafletjs.com/reference.html#map-moveend) event, so if the user is panning the map around, the bbox is only updated when they are done, not in the process.
If the position of the map is updated programmatically using [`flyTo()`](https://leafletjs.com/reference.html#map-flyto) (or `flyToBounds()`), the destination bbox is already set when the animation starts, so that the map data can already be loaded while the animation is in progress.

Wyświetl plik

@ -0,0 +1 @@
# Click listener

Wyświetl plik

@ -0,0 +1 @@
# HashHandler

Wyświetl plik

@ -0,0 +1 @@
# Icons

Wyświetl plik

@ -0,0 +1 @@
# Initial view

Wyświetl plik

@ -0,0 +1,110 @@
# Layers
In Leaflet, a lot of different types of objects are layers internally, for example tile layers, polylines, markers and even tooltips. In the context of FacilMap, there are base layers (tile layers that make up the main map style, only one can be active at a time) and overlays (layers that are shown on top of the base layer). These layers are used in the following way:
* The frontend offers the user to change which base layer and which overlays are visible
* [Saved views](./views) contain information about which base layer and which overlays should be visible
* The [location hash](./hash) stores which base layer and which overlays are visible.
facilmap-leaflet maintains a list of available base layers and overlays. This list is used by the layer picker in the frontend to show the available layers to the user, but it is also used when for views and the location hash to distinguish which layers on a map are FacilMap layers and which are other types of Leaflet layers.
The methods on this page make it possible to add FacilMaps default selection of layers to a map and to modify that selection.
## Get the available layers
To get the available layers, call `getLayers(map)`. It returns an Object whose `baseLayers` and `overlays` properties contain an object that maps a key to a Leaflet layer. The key is used to identify the map in the location hash or in a saved view. The reason why the map has to be passed as an argument is that a Leaflet layer object can only be used on one map at a time. Internally, `getLayers(map)` persists the list of maps in the `_fmLayers` property of the map.
The following example shows how to add a [Leaflet Layers control](https://leafletjs.com/reference.html#control-layers) to the map that shows all the available layers. Note that the control expects objects mapping the layer name to the layer, while the objects returned by `getLayers(map)` map the layer key to the layer, so a mapping has to be done. FacilMap layers use the `fmName` option to store their display name.
```javascript
import L from "leaflet";
import { getLayers } from "facilmap-leaflet";
const map = L.map('map');
const layers = getLayers(map);
const byName = (layerMap) => Object.fromEntries(Object.entries(layerMap).map(([key, layer]) => [layer.options.fmName || key, layer]));
L.control.layers(byName(layers.baseLayers), byName(layers.overlays)).addTo(map);
```
## Change the available layers
To change the available layers for a particular Leaflet map, set the `_fmLayers` properties of that map.
```javascript
import L from "leaflet";
const map = L.map('map');
map._fmLayers = {
baseLayers: {
test: L.tileLayer("...", { fmName: "Test" })
},
overlays: {
ovr1: L.tileLayer("...", { fmName: "Overlay 1" })
}
};
```
To change the available layers for all maps, use `setLayers()`:
```javascript
import { setLayers } from "facilmap-leaflet";
setLayers(() => ({
baseLayers: {
test: L.tileLayer("...", { fmName: "Test" })
},
overlays: {
ovr1: L.tileLayer("...", { fmName: "Overlay 1" })
},
fallbackLayer: "test"
}));
```
Note that `setLayers()` only affects how the `_fmLayers` property is created, it does not affect the `_fmLayers` properties of existing maps. This means that it has to be called before any part of the code accesses the layers of the map.
The FacilMap frontend uses the `fmName` option to decide under which name to show a layer. The layer key needs to be unique and should by convention be 4 characters long.
If you want to extend the default selection of layers, you can get it using `createDefaultLayers()`:
```javascript
import { createDefaultLayers, setLayers } from "facilmap-leaflet";
setLayers(() => {
const layers = createDefaultLayers();
layers.baseLayers.test = L.tileLayer("...", { fmName: "Test" });
layers.overlays.ovr1: L.tileLayer("...", { fmName: "Overlay 1" });
return layers;
}));
```
## Get the visible layers
To find out which of the FacilMap layers are currently visible, use the `getVisibleLayers(map)` function. It returns an object with the following properties:
* `baseLayer`: A string that contains the layer key of the currently visible base layer
* `overlays`: An array of strings with the layer keys of the currently visible overlays
## Set the visible layers
`setVisibleLayers(map, visibleLayers)` can be used with an object of the same shape as returned by `getVisibleLayers(map)`:
```javascript
import L from "leaflet";
import { setVisibleLayers } from "facilmap-leaflet";
const map = L.map('map');
setVisibleLayers(map, { baseLayer: "Mpnk", overlays: ["Hike", "Rlie"] });
```
If `visibleLayers` is not specified, it defaults to `{ baseLayer: "Mpnk", overlays: [] }`.
The helper functions `setBaseLayer(map, baseLayer)` and `toggleOverlay(map, overlay)` can be used to change the visibility of individual layers:
```javascript
import L from "leaflet";
import { setBaseLayer, toggleOverlay } from "facilmap-leaflet";
const map = L.map('map');
setBaseLayer(map, "Mpnk");
toggleOverlay(map, "Hike");
```
To find out the key of an existing layer, open [https://facilmap.org/](https://facilmap.org/), enable the desired layer and find the layer key in the location hash in the address bar of your browser. For example, when Mapnik and Hiking paths are enabled, the URL will look like this: <code>https://facilmap.org/#9/52.5196/13.4069/<strong>Mpnk-Hike</strong></code>.

Wyświetl plik

@ -0,0 +1 @@
# Lines

Wyświetl plik

@ -0,0 +1,5 @@
# Map extensions
## Filter
## Interaction events

Wyświetl plik

@ -0,0 +1 @@
# Markers

Wyświetl plik

@ -0,0 +1 @@
# Route

Wyświetl plik

@ -0,0 +1 @@
# Search

Wyświetl plik

@ -0,0 +1 @@
# Views

Wyświetl plik

@ -6,6 +6,6 @@ The FacilMap server is a HTTP server that fulfills the following tasks:
* Run a socket.io server under `/socket.io`. The frontend connects to this using the [FacilMap client](../client/) and uses it to get calculated routes, get and update the data on a collaborative map, and receive live updates to a collaborative map, and as a proxy to perform searches.
* Maintain a connection to a database where collaborative map data and calculated routes are stored.
The official FacilMap server is running on https://facilmap.org/. If you want, you can run your own FacilMap server using one of these options:
The official FacilMap server is running on [https://facilmap.org/](https://facilmap.org/). If you want, you can run your own FacilMap server using one of these options:
* [Docker](./docker) will run the server in an isolated container. It is easer to set up and more secure, but takes more resources.
* Running the server [standalone](./standalone) takes less resources, but is less secure and takes more steps to set up.

Wyświetl plik

@ -0,0 +1,5 @@
# facilmap-leaflet
facilmap-leaflet provides Leaflet components to show [FacilMap](https://github.com/FacilMap/facilmap) data on a [Leaflet](https://leafletjs.com/) map.
More information can be found in the [documentation](https://docs.facilmap.org/developers/leaflet/).

Wyświetl plik

@ -95,7 +95,6 @@
</div>
<div id="map"></div>
<script src="https://unpkg.com/leaflet"></script>
<script src="https://unpkg.com/socket.io-client/dist/socket.io.js"></script>
<script type="text/javascript" src="dist/facilmap-leaflet.full.js"></script>
<script type="text/javascript">
@ -107,7 +106,7 @@
var client = new FacilMap.Client("http://localhost:40829/");
L.FacilMap.setVisibleLayers(map);
const layers = L.FacilMap.getLayers(map);
const byName = (layerMap) => Object.fromEntries(Object.entries(layerMap).map(([key, layer]) => [layer.options.fmName, layer]));
L.control.layers(byName(layers.baseLayers), byName(layers.overlays)).addTo(map);
@ -120,7 +119,7 @@
linesLayer.setHighlightedLines(new Set());
searchResultsLayer.setHighlightedResults(new Set());
});
const linesLayer = new L.FacilMap.LinesLayer(client).addTo(map)
.on("click", (e) => {
L.DomEvent.stopPropagation(e);
@ -128,7 +127,7 @@
linesLayer.setHighlightedLines(new Set([e.layer.line.id]));
searchResultsLayer.setHighlightedResults(new Set());
});
map.on("click", () => {
markersLayer.setHighlightedMarkers(new Set());
linesLayer.setHighlightedLines(new Set());

Wyświetl plik

@ -25,9 +25,9 @@
"assets",
"dist",
"src",
"./download-icons.ts",
"./example.html",
"./icontest.html",
"download-icons.ts",
"example.html",
"icontest.html",
"README.md",
"tsconfig.json"
],