Skip to content
Snippets Groups Projects
Commit 166e88b2 authored by Anton Sarukhanov's avatar Anton Sarukhanov
Browse files

Keep map view across refreshes with cookie. Cluster bus stops for performance (which still sucks).

parent 85d63a1c
No related branches found
No related tags found
No related merge requests found
......@@ -186,6 +186,7 @@ class Prediction(db.Model, BMModel):
'has_layover': self.has_layover,
'direction': self.direction.tag if self.direction else None,
'vehicle': self.vehicle,
'stop_id': self.stop_id,
}
......
/* This is applied to full-page maps */
html, body {
width: 100%;
height: 100%;
......@@ -9,3 +11,39 @@ html, body {
height: 100%;
width: 100%;
}
/* Bottom-right credits box */
#map .leaflet-control-attribution {
background-color: rgba(0,0,0,.8);
border-top: 1px solid #eee;
border-left: 1px solid #eee;
border-top-left-radius: 3px;
color: #eee;
}
#map .leaflet-control-attribution a,
#map .leaflet-control-attribution a:hover,
#map .leaflet-control-attribution a:visited,
#map .leaflet-control-attribution a:active {
color: #fff;
font-weight: bold;
}
#map div.leaflet-popup a.leaflet-popup-close-button {
display: none;
padding: 2px 2px 0 0;
}
#map div.leaflet-popup div.leaflet-popup-content-wrapper {
border: 3px solid #666;
background: #222;
color: #eee;
}
#map div.leaflet-popup div.leaflet-popup-tip {
background-color: #666;
}
#map div.leaflet-popup div.leaflet-popup-content {
margin: .5em .66em;
}
#map div.leaflet-popup div.leaflet-popup-content header {
font-weight: bold;
font-size: 1.3em;
color: #fff;
}
......@@ -2,4 +2,3 @@ body {
padding-top: 50px;
padding-bottom: 30px;
}
static/img/stop.png

8.36 KiB

static/img/stop27x60.png

533 B

......@@ -30,10 +30,22 @@ BusMap.Map = function(opts) {
else {that.leaflet.fitBounds(that.opts.bounds)}
if (that.opts.zoom) that.leaflet.setZoom(that.opts.zoom);
// Restore the user's last view.
goToLastView();
// Bind map event handlers
that.leaflet.on('moveend', function() {
// Store the lat/lon/zoom so we can restore it later
updateLastView();
});
// Configure and apply the map tile layer
var tileUrl = that.opts.tileUrl;
var tileOptions = {}
if (that.opts.tileOptions) { tileOptions = that.opts.tileOptions; }
var tileOptions = {
};
if (that.opts.tileOptions) {
for (o in that.opts.tileOptions) { tileOptions[o] = that.opts.tileOptions[o]; }
}
L.tileLayer(tileUrl, tileOptions).addTo(that.leaflet);
// Fetch initial data
......@@ -56,34 +68,11 @@ BusMap.Map = function(opts) {
"dataset": "routes",
"agency": that.opts.agency,
};
function updateStopsUI(stops) {
for (var s in stops) {
// TODO: Put the stop marker on the map.
var markerIcon = L.icon({
iconUrl: 'http://rutge.rs/img/bluedot.png',
iconSize: [24,24],
// options
});
var text = '<header>' + stops[s].title + '</header>';
var markerOpts = {
icon: markerIcon,
title: stops[s].title,
opacity: 1,
};
var popupOpts = {
closeButton: true,
keepInView: true,
};
stopMarkers[stops[s].tag + "*" + stops[s].route] = L.marker(
[stops[s].lat, stops[s].lon],
markerOpts).addTo(that.leaflet);
}
}
$.getJSON(url, params)
.done(function(data) {
stops = data.stops;
routes = data.routes;
updateStopsUI(stops);
that.stops = data.stops;
that.routes = data.routes;
updateStopsUI(that.stops);
console.log(data);
});
return that;
......@@ -98,12 +87,141 @@ BusMap.Map = function(opts) {
};
$.getJSON(url, params)
.done(function(data) {
/* TODO: Fix all this shit, what the fuck */
for (var p in data.predictions) {
pr = data.predictions[p];
// Store this prediction on the stop and on the vehicle.
}
that.vehicles = data.locations;
updateStopsUI(that.stops);
console.log(data);
});
// todo
return that;
};
/* Refresh (and/or create) UI elements for Vehicles */
function updateVehiclesUI(vehicles) {
// TODO
return that;
}
/* Refresh (and/or create) UI elements for Stops */
function updateStopsUI(stops) {
var markers = L.markerClusterGroup({
disableClusteringAtZoom: 14,
maxClusterRadius: 40,
showCoverageOnHover: false,
zoomToBoundsOnClick: false,
});
for (var s in stops) {
var markerIcon = L.icon({
iconUrl: 'static/img/stop27x60.png',
iconSize: [13, 30],
iconAnchor: [6, 30],
});
var text = '<header>' + stops[s].title + '</header>';
var predictions = ['No vehicle arrival predictions.'];
predictions.push('No vehicle arrival predictions.');
if (stops[s].predictions) {
var predictions = [];
for (rt in stops[s].predictions) {
// do shit with prediction
}
}
text += '<section class="predictions">' + predictions.join("<br>") + '</section>';
var markerOpts = {
title: stops[s].title,
icon: markerIcon,
opacity: 1,
};
var popupOpts = {
closeButton: true,
keepInView: true,
};
stopMarkers[stops[s].tag + "*" + stops[s].route] = L.marker(
[stops[s].lat, stops[s].lon],
markerOpts).bindPopup(text, popupOpts);
markers.addLayer(stopMarkers[stops[s].tag + "*" + stops[s].route]);
}
that.leaflet.addLayer(markers);
return that;
}
function goToLastView() {
var last = BusMap.getCookie('last_view');
if (last && last != "") {
last = last.split(",");
that.leaflet.setView(L.latLng(last[0], last[1]), last[2]);
return true;
} else {
return false;
}
}
function updateLastView() {
var ll = that.leaflet.getCenter();
view = ll.lat + ',' + ll.lng + ',' + that.leaflet.getZoom();
BusMap.setCookie('last_view', view);
}
return that;
};
// http://stackoverflow.com/a/4004010
if (typeof String.prototype.trimLeft !== "function") {
String.prototype.trimLeft = function() {
return this.replace(/^\s+/, "");
};
}
if (typeof String.prototype.trimRight !== "function") {
String.prototype.trimRight = function() {
return this.replace(/\s+$/, "");
};
}
if (typeof Array.prototype.map !== "function") {
Array.prototype.map = function(callback, thisArg) {
for (var i=0, n=this.length, a=[]; i<n; i++) {
if (i in this) a[i] = callback.call(thisArg, this[i]);
}
return a;
};
}
BusMap.getCookies = function() {
var c = document.cookie, v = 0, cookies = {};
if (document.cookie.match(/^\s*\$Version=(?:"1"|1);\s*(.*)/)) {
c = RegExp.$1;
v = 1;
}
if (v === 0) {
c.split(/[,;]/).map(function(cookie) {
var parts = cookie.split(/=/, 2),
name = decodeURIComponent(parts[0].trimLeft()),
value = parts.length > 1 ? decodeURIComponent(parts[1].trimRight()) : null;
cookies[name] = value;
});
} else {
c.match(/(?:^|\s+)([!#$%&'*+\-.0-9A-Z^`a-z|~]+)=([!#$%&'*+\-.0-9A-Z^`a-z|~]*|"(?:[\x20-\x7E\x80\xFF]|\\[\x00-\x7F])*")(?=\s*[,;]|$)/g).map(function($0, $1) {
var name = $0,
value = $1.charAt(0) === '"'
? $1.substr(1, -1).replace(/\\(.)/g, "$1")
: $1;
cookies[name] = value;
});
}
return cookies;
}
BusMap.getCookie = function(name) {
console.log("Getting cookie\n" + "BM-" + name);
return BusMap.getCookies()["BM-" + name];
}
BusMap.setCookie = function(name, value, exp_days) {
if (exp_days == undefined) {
exp_days = 365;
}
exp_date = new Date();
exp_date.setDate(exp_date.getDate() + exp_days);
value = escape(value) + "; expires=" + exp_date.toUTCString();
console.log("Setting cookie\n" + "BM-" + name + "=" + value);
document.cookie = "BM-" + name + "=" + value;
}
......@@ -2,6 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>{% block title %}{% endblock %}</title>
{% block head %}
{% endblock %}
......
{% extends "base.html" %}
{% block title %}Bus Map{% endblock %}
{% block title -%}
{% if agency.short_title %}{{ agency.short_title -}}
{% elif agency.title %}{{ agency.title }}{% endif %} Bus Map
{%- endblock %}
{% block head %}
{{ super() }}
<link href="bower/leaflet/dist/leaflet.css" rel="stylesheet"/>
<link href="bower/leaflet.markercluster/dist/MarkerCluster.Default.css" rel="stylesheet"/>
<link href="static/css/full-page-map.css" rel="stylesheet" />
{% endblock %}
{% block body %}
<div id="map"></div>
<script src="bower/leaflet/dist/leaflet.js"></script>
<script src="bower/leaflet.markercluster/dist/leaflet.markercluster.js"></script>
<script src="bower/jquery/dist/jquery.min.js"></script>
<script src="static/js/map.js"></script>
<script>
......@@ -18,8 +23,8 @@
tileOptions: {
subdomains: {{ config['MAP_TILE_SUBDOMAINS']|tojson|safe }},
attribution: '{{ config['MAP_CUSTOM_ATTRIBUTION']|safe }}'
+ '<br>Map Data &copy; {{ config['MAP_DATA_ATTRIBUTION']|safe }}'
+ '<br>Bus Data &copy; {{ agency.title }}',
+ ' | Data &copy; {{ config['MAP_DATA_ATTRIBUTION']|safe }}'
+ ', {{ agency.title }}',
tileset: '{{ config['MAP_TILESET']|safe }}',
errorTileUrl: '{{ config['MAP_ERROR_TILE_URL']|safe }}',
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment