Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nekromoff/bicycle-master-plan
Bicycle Master Plan is a bike map that allows visualizing cycling related data from different sources in multiple layers. Built heavily around data from OpenStreetMap, it allows full visual customization using CSS.
https://github.com/nekromoff/bicycle-master-plan
app bicycle bicycle-infrastructure bike cycling cycling-safety exif-tags google-sheets gps-data map mapping mapping-tools maps mapserver markers openstreetmap openstreetmaps osm overpass-api overpass-turbo
Last synced: about 2 months ago
JSON representation
Bicycle Master Plan is a bike map that allows visualizing cycling related data from different sources in multiple layers. Built heavily around data from OpenStreetMap, it allows full visual customization using CSS.
- Host: GitHub
- URL: https://github.com/nekromoff/bicycle-master-plan
- Owner: nekromoff
- License: gpl-3.0
- Created: 2019-03-20T16:52:26.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2023-10-17T22:41:40.000Z (about 1 year ago)
- Last Synced: 2024-10-12T16:51:05.055Z (2 months ago)
- Topics: app, bicycle, bicycle-infrastructure, bike, cycling, cycling-safety, exif-tags, google-sheets, gps-data, map, mapping, mapping-tools, maps, mapserver, markers, openstreetmap, openstreetmaps, osm, overpass-api, overpass-turbo
- Language: PHP
- Homepage: https://mapa.cyklokoalicia.sk/bratislava/public/
- Size: 635 KB
- Stars: 11
- Watchers: 3
- Forks: 0
- Open Issues: 9
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# Bicycle Master Plan
Bicycle Master Plan is a tool / web app for displaying various bicycle infrastructure related data on a map. Actually, you can use any OpenStreetMap / custom data on a map, not just bicycle-related data. Extensive visual customization is possible by automatical conversion of OSM keys and values to CSS classes.It supports the following sources of data:
- OSM data (JSON format; tiles, paths/ways and markers)
- database data (seed your database; markers)
- GPS EXIF-tagged photos (automatic using default seeder; markers)
- custom feed data (from any public URL/API in JSON format; markers)
- custom data (from rows in Google Sheets; markers only)
- data provided by users via form (if editable layer enabled; markers)Built with:
- Laravel (PHP)
- Leaflet (JS)## Demo / working version for the city of Bratislava:
https://mapa.cyklokoalicia.sk/bratislava/public/## Installation
1. download the code (git clone or ZIP file)
2. run `composer install` to download dependencies
3. run `php artisan migrate` to setup database
4. check/set `public/.htaccess` file permissions, if necessary
5. check/set `storage/app/` permissions, if necessary (755 for writing)
6. create `storage/app/public/uploads/` directory (755), if an editable layer is enabled
7. create `storage/app/osm/` directory (755), if OSM layer download is enabled (see below)
8. symlink `public/storage/` (TARGET) to `storage/app/public/uploads/` (SOURCE), if an editable layer is enabled (see https://laravel.com/docs/7.x/filesystem#the-public-disk)## Configuration
1. Edit `config/map.php`
- Set basic info such as map name, language, bounding box, center and zoom
- Configure `layers`:
- a base layer (usually a background map tile layer) is always `0` in config file
- `type` = `path`, `marker`, `combined`
- `name` = name of a layer (can contain HTML tags)
- `class` = CSS class to be used to mark up layer items (markers / paths)
- `icon` = layer item icon (markers only) will be created from either `name` or `filename` in database
- *optional* `file` = OSM JSON file containing layer content (markers or paths/ways downloaded from OSM)
- *optional* `cluster` = `true` for layers to group/cluster items/markers
- *optional* `editable` = `true` for the user editable layer (user submitted items require admin approval, see below)
- *optional* `types` = *array* a layer can contain multiple types of items such as different sets of markers etc.
- *optional* Configure OSM data/layers to download:
- `osm_server` = `https://lz4.overpass-api.de/api/interpreter` (use any OSM server)
- `osm_data` = *array* of map layers with `file` parameter:
- `file` = filename to save the file
- `data` = overpass query to download OSM data, e.g. `[out:json]; (relation[network=lcn]({{bbox}}); ); out body; >; out skel qt;`, see https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_API_by_Example
- *optional* Configure admin emails (see below on how to enable admin functionality):
- `admins` = *array* of admin emails, e.g. ['[email protected]', '[email protected]']
2. *optional* If you enable an editable layer, user submitted items require admin approval to be displayed. Set `approved` column to `1` in database. If user marked an item as `outdated` (`1` in database), set `deleted` to `1` in database to hide it from a map.
3. *optional* If you want to display bikeshare data on your map, see file `config/bikeshare.example.php` for details on how to enable data download (public bikeshare API endpoint required)
4. *optional* If you want to display additional custom data/markers on your map from **Google Sheets**, see `config/google.example.php` file on how to configure it (you will need to create a project with service access with `client_id` and JSON `keyfile` at https://console.developers.google.com)
5. *optional* If you require admin functionality, you will need to obtain client ID + client secret from OAuth2 credentials at https://console.developers.google.com. Once you have these, edit `config/services.php` and add the following lines:
```
'google' => [
'client_id' => 'your_client_id',
'client_secret' => 'your_client_secret',
'redirect' => 'callback URL', // callback URL for OAuth authentication, e.g. http://example.com/login/google/callback
],
```## Customization / map style
All standard map tiles providers are supported.Open `public/css/main.css` to customize layer markers or styles of paths etc. SVG properties (`fill`, `stroke` etc.) need to be used for styling paths/OSM ways, see https://css-tricks.com/svg-properties-and-css/.
Example of path classes created from OpenStreetMap data (bicycle lane):
```
class="path cycleway-left-lane cycleway-right-shared_lane foot-use_sidepath highway-residential lit-yes maxspeed-30 name-dunajska name-hu-dunautca surface-asphalt trolley_wire-yes"
```Example of marker classes created from OpenStreetMap data (bicycle parking):
```
class="marker access-private amenity-bicycle_parking covered-yes surveillance-yes parking"
```Any combinations of keys / values can be easily styled for your purposes by using standardized CSS.
## Automatic data update
Setup cron to call refresh URLs daily (or other interval), e.g.:
```
15 0 * * * /usr/bin/curl --silent https://example.com/public/refresh/osm >/dev/null 2>&1
```
Update endpoints are:
- OSM data: `/refresh/osm`
- Bikeshare feed data: `/refresh/bikeshare`
- Google sheets data: `/refresh/googlesheet`
- Feed data: `/refresh/feed`## Examples
### Markers created from photos automatically
1. Upload photos/files to `public/photos` directory (create this directory, if it does not exist)
2. run `php artisan db:seed --class=PhotosSeeder`
3. Seeder will process all photos in the directory and extract their GPS coordinates from EXIF tags and add them to database as markers
4. Enable photo layer by editing `config/map.php` (enabling clustering will help with large number of photos) and adding this code to `layers`:
```
1 => [
'type' => 'marker',
'name' => 'Your photos',
'class' => 'photo',
'icon' => 'filename',
'cluster' => true,
'options' => [
'disableClusteringAtZoom' => 17,
],
],
```
5. Refresh your map to see your photos### OpenStreeMap cycling paths and bike sharing stations
1. Edit `config/map.php` and add a layer (change number `5` to suit your purposes) to the `layers`:
```
5 => [
'type' => 'path',
'name' => 'Cycling paths
━━━ Segregated
━━━ Shared
• • • • Recommended
━━━ Pedestrianized
━━━ For mountain bikes',
'class' => 'ways',
'file' => 'ways.json',
],
```
2. Add OSM instructions for fetching data in `config/map.php`. Change `network` operator name to your city's one (e.g. `Slovnaft BAjk` for Bratislava):
```
// OSM data to fetch
'osm_server' => 'https://lz4.overpass-api.de/api/interpreter',
'osm_data' => [
[
'file' => 'ways.json',
'data' => '[out:json]; (way[cycleway]({{bbox}}); way["cycleway:left"]({{bbox}}); way["cycleway:right"]({{bbox}}); way[highway=pedestrian]({{bbox}}); way[highway=cycleway]({{bbox}}); way[bicycle=yes]({{bbox}}); way[bicycle=official]({{bbox}}); way[lcn]({{bbox}}); way[bicycle=designated]({{bbox}}); ); out body; >; out skel qt;',
],
[
'file' => 'bikeshare-sb.json',
'data' => '[out:json]; (node[network="Slovnaft BAjk"]({{bbox}}); ); out body; >; out skel qt;',
],
],
```### Bicycle parking stands from OpenStreeMap
1. Edit `config/map.php` and add a layer (change number `2` to suit your purposes) to the `layers`:
```
2 => [
'type' => 'marker',
'name' => 'Bicycle parking
Safe
Unsuitable
Public pump and tools',
'class' => 'parking',
'file' => 'parking.json',
],
```
2. Add OSM instructions for fetching data in `config/map.php`:
```
'osm_server' => 'https://lz4.overpass-api.de/api/interpreter',
'osm_data' => [
[
'file' => 'parking.json',
'data' => '[out:json]; (node[amenity="bicycle_parking"]({{bbox}}); node["amenity"="bicycle_repair_station"]({{bbox}}); ); out body; >; out skel qt;',
],
],
```