Add tile server capability.

bearings
Mark Jessop 2018-08-02 20:49:36 +09:30
rodzic 24a4ac161f
commit 7350a85938
5 zmienionych plików z 83 dodań i 10 usunięć

Wyświetl plik

@ -61,9 +61,20 @@ At the moment Chasemapper only supports receiving chase-car positions via Horus
Eventually support will be added to get car positions from either GPSD, or from the client's device.
## Offline Mapping
## Offline Mapping via FoxtrotGPS's Tile Cache
(This is a work in progress)
By default Chasemapper is configured to use the online OSM and ESRI Satellite tileservers. There is also an 'offline OSM' entry in the map layer list (top right of the page), which attempt to gather maps from `http://server_ip:8080/roads/{z}/{x}/{y}.png`. I've been doing some testing with using [Tilestache](http://tilestache.org/) as a lightweight tileserver, serving tiles from mbtiles files. A guide on how to cache up OSM data for use with Tilestache is TBD...
Chasemapper can serve up map tiles from a specified directory to the web client. Of course, for this to be useful, we need map tiles to server! [FoxtrotGPS](https://www.foxtrotgps.org/) can help us with this, as it caches map tiles to `~/Maps/`, with one subdirectory per map layer (i.e. `~/Maps/OSM/`, `~/Maps/opencyclemap/`).
This can be enabled by setting `[offline_maps] tile_server_enabled = True`, and changing `[offline_maps] tile_server_path` to point to your tile cache directory (i.e. `/home/pi/Maps/`). Chasemapper will assume each subdirectory in this folder is a valid map layer and will add them to the map layer list at the top-right of the interface.
### Caching Maps
To grab map tiles to use with this, we're going to use FoxtrotGPS's [Cached Maps](https://www.foxtrotgps.org/doc/foxtrotgps.html#Cached-Maps) feature.
* Install FoxtrotGPS (Linux only unfortunately, works OK on a Pi!) either [from source](https://www.foxtrotgps.org/releases/), or via your system package manager (`sudo apt-get install foxtrotgps`).
* Load up FoxtrotGPS, and pan around the area you are intersted in caching. Pick the map layer you want, right-click on the map, and choose 'Map download'. You can then select how many zoom levels you want to cache, and start it downloading (this may take a while!)
* Once you have a set of folders within your `~/Maps` cache directory, you can startup Chasemapper and start using them! Tiles will be served up as they become available.
(If anyone has managed to get ECW support working in GDAL recently, please contact me! I would like to convert some topographic maps in ECW format to tiles for use with Chasemapper.)

Wyświetl plik

@ -6,6 +6,7 @@
# Released under GNU GPL v3 or later
#
import logging
import os
try:
# Python 2
@ -61,6 +62,19 @@ def parse_config_file(filename):
chase_config['pred_gfs_directory'] = config.get('predictor', 'gfs_directory')
chase_config['pred_model_download'] = config.get('predictor', 'model_download')
# Offline Map Settings
chase_config['tile_server_enabled'] = config.getboolean('offline_maps', 'tile_server_enabled')
chase_config['tile_server_port'] = config.getint('offline_maps', 'tile_server_port')
chase_config['tile_server_path'] = config.get('offline_maps', 'tile_server_path')
# Determine valid offline map layers.
chase_config['offline_tile_layers'] = []
if chase_config['tile_server_enabled']:
for _dir in os.listdir(chase_config['tile_server_path']):
if os.path.isdir(os.path.join(chase_config['tile_server_path'],_dir)):
chase_config['offline_tile_layers'].append(_dir)
logging.info("Found Map Layers: %s" % str(chase_config['offline_tile_layers']))
# Telemetry Source Profiles
_profile_count = config.getint('profile_selection', 'profile_count')
@ -121,6 +135,7 @@ def read_config(filename, default_cfg="horusmapper.cfg.example"):
if __name__ == "__main__":
import sys
logging.basicConfig(format='%(asctime)s %(levelname)s:%(message)s', stream=sys.stdout, level=logging.DEBUG)
print(read_config(sys.argv[1]))

Wyświetl plik

@ -91,3 +91,22 @@ gfs_directory = ./gfs/
# The gfs directory (above) will be cleared of all .dat files prior to the above command being run.
model_download = none
#
# Offline Tile Server
#
# Allows serving of map tiles from a directory.
# Each subdirectory is assumed to be a separate layer of map tiles, i.e. 'OSM', 'opencyclemap',
# and is added to the map interface as a separate layer.
# This feature can be used to serve up FoxtrotGPS's tile cache as layers, usually located in ~/Maps/
#
[offline_maps]
# Enable serving up maps from a directory of map tiles.
tile_server_enabled = False
# Path to map tiles. For FoxtrotGPS, this is usually ~/Maps/
# NOTE: This must be an ABSOLUTE directory, i.e. /home/pi/Maps/ - ~/Maps/ will not work.
tile_server_path = /home/pi/Maps/

Wyświetl plik

@ -9,6 +9,7 @@ import json
import logging
import flask
from flask_socketio import SocketIO
import os.path
import sys
import time
import traceback
@ -48,6 +49,9 @@ data_listeners = []
# These settings are not editable by the client!
pred_settings = {}
# Offline map settings, again, not editable by the client.
map_settings = {'tile_server_enabled': False}
# Payload data Stores
current_payloads = {} # Archive data which will be passed to the web client
current_payload_tracks = {} # Store of payload Track objects which are used to calculate instantaneous parameters.
@ -75,6 +79,19 @@ def flask_get_telemetry_archive():
def flask_get_config():
return json.dumps(chasemapper_config)
@app.route("/tiles/<path:filename>")
def flask_server_tiles(filename):
""" Serve up a file from the tile server location """
global map_settings
if map_settings['tile_server_enabled']:
_filename = flask.safe_join(map_settings['tile_server_path'], filename)
if os.path.isfile(_filename):
return flask.send_file(_filename)
else:
flask.abort(404)
else:
flask.abort(404)
def flask_emit_event(event_name="none", data={}):
""" Emit a socketio event to any clients. """
@ -692,6 +709,12 @@ if __name__ == "__main__":
'pred_model_download': chasemapper_config['pred_model_download']
}
# Copy out Offline Map Settings
map_settings = {
'tile_server_enabled': chasemapper_config['tile_server_enabled'],
'tile_server_path': chasemapper_config['tile_server_path']
}
# Start listeners using the default profile selection.
start_listeners(chasemapper_config['profiles'][chasemapper_config['selected_profile']])

Wyświetl plik

@ -51,6 +51,7 @@
pred_update_rate: 15,
pred_model: 'Disabled',
show_abort: true, // Show a prediction of an 'abort' paths (i.e. if the balloon bursts *now*)
offline_tile_layers: []
};
// Object which will contain balloon markers and traces.
@ -198,13 +199,6 @@
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
// Experimental offline maps using a local tilestache server.
var offline_osm_map = L.tileLayer(location.protocol + '//' + document.domain + ':8080/roads/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
minNativeZoom:9,
maxNativeZoom:13
});
// Add ESRI Satellite Maps.
var esrimapLink =
'<a href="http://www.esri.com/">Esri</a>';
@ -216,7 +210,18 @@
attribution: '&copy; '+esrimapLink+', '+esriwholink,
maxZoom: 18,
});
map.addControl(new L.Control.Layers({'OSM':osm_map, 'ESRI Satellite':esri_sat_map, 'Offline OSM': offline_osm_map}));
var map_layers = {'OSM':osm_map, 'ESRI Satellite':esri_sat_map};
// Add Offline map layers, if we have any.
for (var i = 0, len = chase_config.offline_tile_layers.length; i < len; i++) {
var _layer_name = chase_config.offline_tile_layers[i];
map_layers['Offline - ' + _layer_name] = L.tileLayer(location.protocol + '//' + document.domain + ':' + location.port + '/tiles/'+_layer_name+'/{z}/{x}/{y}.png');
}
// Add layer selection control (top right).
map.addControl(new L.Control.Layers(map_layers));
// Add sidebar to map (where all of our controls are!)
var sidebar = L.control.sidebar('sidebar').addTo(map);
// Add custom controls, which show various sets of data.