Commit 738c5a61 authored by Adrien Pavie's avatar Adrien Pavie
Browse files

SideContent Layers created, displays styles and base layers, also mapcss styles improved

parent 3f7d23df
......@@ -30,6 +30,7 @@ TEST_VIEWS = \
MessagesTest.js \
SideContent_FeatureTest.js \
SideContent_HelpTest.js \
SideContent_LayersTest.js \
SideContent_NewNoteTest.js \
SideContent_NotesTest.js \
SideContent_SearchTest.js \
......
......@@ -13,7 +13,9 @@ Here is a list of MapCSS 0.2 properties that are supported by OpenLevelUp. See
[MapCSS definition](http://wiki.openstreetmap.org/wiki/MapCSS/0.2) for details.
### Meta
Meta properties (describing the stylesheets) are supported. However, only `title` is read by OpenLevelUp.
Meta properties (describing the stylesheets) are supported. In fact, for proper rendering, two meta properties are mandatory:
* `title`: the name of the style
* `icon-image`: an icon representing the style
### Canvas
Canvas properties aren't supported. For background customization you should use configuration files.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -129,27 +129,6 @@
}
],
"railway|public_transport": [
{
"name": "${railway} (rail)",
"description": "Rail",
"onTags": [ { "railway": "rail|subway|light_rail|monorail|narrow_gauge|tram" } ],
"style": { "color": "#888888", "opacity": 1, "weight": 10, "lineCap": "butt", "dashArray": "5,5", "label": "name", "labelStyle": "railway" }
},
{
"name": "Platform",
"description": "Railway platform",
"onTags": [ { "railway": "platform" }, { "public_transport": "platform" } ],
"style": { "color": "#B4ADB3", "opacity": 1, "weight": 1, "fillColor": "#BABABA", "fillOpacity": 1, "layer": -8 }
},
{
"name": "${railway}",
"description": "Railway icons",
"onTags": [ { "railway": "platform|subway_entrance|buffer_stop" } ],
"style": { "icon": "railway_${railway}.png" }
}
],
"shop": [
{
"name": "${shop} (shop)",
......
/*
* This file is part of OpenLevelUp!.
*
* OpenLevelUp! is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* OpenLevelUp! is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenLevelUp!. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Styles for OLU.view.sidecontent.Layers
*/
/*
* Layers buttons
*/
.side-content-layers-button {
height: 50px;
border: 3px solid #08296B;
border-radius: 5px;
margin-bottom: 10px;
font-size: 1.2em;
font-weight: bold;
cursor: pointer;
position: relative;
overflow: hidden;
}
.side-content-layers-button:hover {
border-color: #85A4E3;
background-color: rgba(255,255,255,0.3) !important;
}
.side-content-layers-button.selected {
border-color: #51A74C;
}
/*
* Map styles buttons
*/
.side-content-layers-button.style {
background-color: rgba(255,255,255,0.2);
}
.side-content-layers-button.style img {
vertical-align: middle;
height: 30px;
max-width: 30px;
margin: 10px;
}
/*
* Base layers buttons
*/
.side-content-layers-button.base {
height: 70px;
}
.side-content-layers-button.base img {
display: block;
position: absolute;
width: 100%;
z-index: -1;
top: -100%;
min-width: 256px;
}
.side-content-layers-button.base span {
background-color: rgba(255,255,255,0.9);
color: #555;
padding: 5px 8px;
line-height: 70px;
}
......@@ -37,5 +37,6 @@
@import "./OLU.SideContent.Notes.css";
@import "./OLU.SideContent.Search.css";
@import "./OLU.SideContent.Feature.css";
@import "./OLU.SideContent.Layers.css";
@import "./OLU.Spinner.css";
@import "./OLU.Main.css";
......@@ -59,10 +59,11 @@ var OLU = {
sidecontent: {
Feature: require("./view/sidecontent/Feature"),
Help: require("./view/sidecontent/Help"),
Layers: require("./view/sidecontent/Layers"),
Notes: require("./view/sidecontent/Notes"),
Parameters: require("./view/sidecontent/Parameters"),
Routing: require("./view/sidecontent/Routing"),
Search: require("./view/sidecontent/Search"),
Search: require("./view/sidecontent/Search")
}
},
ctrl: {
......
......@@ -10,6 +10,7 @@ var StyleList = function() {
this.textStyles = {};
this.pointStyles = {};
this.shieldStyles = {};
this.metaStyles = {};
};
StyleList.prototype = {
......@@ -20,7 +21,7 @@ StyleList.prototype = {
hasStyles:function() {
// summary: Does this StyleList contain any styles?
return (this.hasShapeStyles() || this.hasTextStyles() || this.hasPointStyles() || this.hasShieldStyles());
return (this.hasShapeStyles() || this.hasTextStyles() || this.hasPointStyles() || this.hasShieldStyles() || this.hasMetaStyles());
},
hasFills:function() {
......@@ -57,13 +58,15 @@ StyleList.prototype = {
for (k in this.textStyles ) { str+="- TS "+k+"="+this.textStyles[k]+"\n"; }
for (k in this.pointStyles ) { str+="- PS "+k+"="+this.pointStyles[k]+"\n"; }
for (k in this.shieldStyles) { str+="- sS "+k+"="+this.shieldStyles[k]+"\n"; }
for (k in this.metaStyles ) { str+="- MS "+k+"="+this.metaStyles[k]+"\n"; }
return str;
},
hasShapeStyles:function() { for (var a in shapeStyles ) { return true; } return false; },
hasTextStyles:function() { for (var a in textStyles ) { return true; } return false; },
hasPointStyles:function() { for (var a in pointStyles ) { return true; } return false; },
hasShieldStyles:function() { for (var a in shieldStyles) { return true; } return false; }
hasShieldStyles:function() { for (var a in shieldStyles) { return true; } return false; },
hasMetaStyles:function() { for (var a in metaStyles ) { return true; } return false; }
};
module.exports = StyleList;
......@@ -96,6 +96,11 @@ util.addCompatibility = function() {
};
}());
}
//Number.toRad()
if(!Number.toRad) {
Number.prototype.toRad = function () { return this * Math.PI / 180; };
}
};
/**
......
......@@ -428,110 +428,6 @@ var Main = function(divId, mode, config, rulesets, newNoteService, searchService
this.level.setCurrent(level);
}
}
// //Few details
// if(this.mode == "basic") {
// //Download new data
// if(this.bounds.features == undefined || !this.bounds.features.contains(bounds)) {
// this.spinner.show("Retrieving building data", "download");
// this.bounds.features = bounds.pad(1.1 + 0.5 * (zoom - this.config.view.map.data_min_zoom));
//
// //Retrieve pictures
// this.pictures.flickr = null;
// flickrProvider.get(
// this.bounds.features,
// function(photos) {
// this.pictures.flickr = photos;
// }.bind(this),
// function() {
// this.messages.show("Flickr pictures can't be retrieved", "error");
// }.bind(this)
// );
//
// //Features data
// console.log("[Main] Start download features data");
// osmProvider.download(
// this.bounds.features,
// function(d) {
// //Associate pictures to features
// if(this.pictures.flickr != null) {
// for(var id in this.pictures.flickr) {
// if(d.features[id] != undefined) {
// for(var picId = 0; picId < this.pictures.flickr[id].length; picId++) {
// d.features[id].getImages().addFlickrImage(
// this.pictures.flickr[id][picId].url,
// this.pictures.flickr[id][picId].date,
// this.pictures.flickr[id][picId].author,
// this.pictures.flickr[id][picId].authorId,
// this.pictures.flickr[id][picId].imgId
// );
// }
// }
// }
// }
//
// if(this._lastFeatures) { delete this._lastFeatures; }
// this._lastFeatures = d;
//
// this.layersManager.setOSMFeatures(
// d,
// this.rulesets[this.currentRuleset],
// {
// folder: this.config.view.icons.folder,
// size: this.config.view.icons.size,
// clickHandler: function(feature) {
// this.side.contents.feature.set(
// feature,
// this.config.feature.details,
// {
// iconFolder: this.config.view.icons.folder,
// mapillaryClient: this.config.images.mapillary.clientId
// }
// );
// this.side.show("feature");
// }.bind(this)
// }
// );
//
// this.spinner.hide();
// }.bind(this),
// function(e) {
// this.messages.show(e.message || "Can't retrieve data", "error");
// this.spinner.hide();
// }.bind(this)
// );
// }
// //Reload existing data
// else if(this.layersManager.layers.features != null) {
// //Check first if one of the feature levels is shown
// var level = null;
// var levels = Object.keys(this.layersManager.layers.features);
// var currentLevel = (this.level.map == null) ? null : this.level.level;
//
// for(var i in this.layersManager.layers.features) {
// if(this.layers.data == this.layersManager.layers.features[i]) {
// level = i;
// break;
// }
// }
//
// if(level === null) {
// level = (levels.indexOf(0) >= 0) ? 0 : levels[0];
// }
//
// if(level != currentLevel) {
// levelChangedHandler({ level: level });
// if(this.level.map == null) {
// this.level.addTo(this.map);
// }
// this.level.setAvailable(levels);
// this.level.setCurrent(level);
// }
// }
// }
// //All details
// else {
// //TODO
// }
this.buttons.note.enable();
}
......
......@@ -125,7 +125,8 @@ MapLayersManager.prototype.setOSMFeatures = function(f, ruleset, options) {
var feature, fid, fLayer, fStyle, fLayerEdited, fClickHandler;
var fLevel, fIconUrl, fIconCoords, fIconAngle, coord1, coord2;
var midSegment, fIconRgxTagName, fIconRgxTagValue;
var midSegment, fIconRgxTagName, fIconRgxTagValue, fTextOffset;
var fHasIcon;
var fIconRgx = /\$\[(\w+)\]/;
fClickHandler = options.clickHandler;
......@@ -138,8 +139,9 @@ MapLayersManager.prototype.setOSMFeatures = function(f, ruleset, options) {
//Create feature layer
fLayer = L.featureGroup();
fLayerEdited = false;
fHasIcon = false;
// if(fid == "node/3652512272") {
// if(fid == "relation/5444317") {
// console.log(feature);
// console.log(feature.style);
// }
......@@ -210,6 +212,7 @@ MapLayersManager.prototype.setOSMFeatures = function(f, ruleset, options) {
));
fLayerEdited = true;
fHasIcon = true;
}
}
......@@ -261,11 +264,17 @@ MapLayersManager.prototype.setOSMFeatures = function(f, ruleset, options) {
fIconAngle = null;
}
//Text offset
fTextOffset = (!isNaN(fStyle.text_offset)) ? (fStyle.text_offset) : 0;
if(fHasIcon) {
fTextOffset -= ((!isNaN(fStyle.icon_height)) ? fStyle.icon_height : options.size) / 2 + 5;
}
fLayer.addLayer(this._createLabel(
fIconCoords,
feature.getTag(fStyle.text),
fStyle,
(!isNaN(fStyle.text_offset)) ? fStyle.text_offset : 0,
fTextOffset,
fIconAngle
));
......@@ -354,7 +363,7 @@ MapLayersManager.prototype._createLabel = function(coordinates, text, styles, of
className: 'feature-label',
html: '<div style="'+cssStyles+'">'+text+'</div>',
iconAnchor: [ null, offset ],
iconSize: [ 70, null ]
iconSize: [ ((angle) ? 200 : 70), null ]
}),
draggable: false
});
......
......@@ -25,6 +25,7 @@ var SideContentNewNote = require('./sidecontent/NewNote');
var SideContentParameters = require('./sidecontent/Parameters');
var SideContentHelp = require('./sidecontent/Help');
var SideContentFeature = require('./sidecontent/Feature');
var SideContentLayers = require('./sidecontent/Layers');
/**
* Side is a side panel which shows several contents (configuration, search results, ...)
......@@ -38,7 +39,8 @@ var Side = L.Control.Sidebar.extend({
newnote: new SideContentNewNote(),
parameters: new SideContentParameters(),
help: new SideContentHelp(),
feature: new SideContentFeature()
feature: new SideContentFeature(),
layers: new SideContentLayers()
},
halfsize: [ "search", "routing", "notes", "newnote", "feature" ],
......
/*
* This file is part of OpenLevelUp!.
*
* OpenLevelUp! is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* OpenLevelUp! is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with OpenLevelUp!. If not, see <http://www.gnu.org/licenses/>.
*/
var $ = require('jquery');
/**
* Layers content for side bar
*/
var Layers = function() {
//ATTRIBUTES
/** The base layers **/
this._bases = null;
/** The map styles **/
this._styles = null;
/** The map coordinates **/
this._coords = { lat: 48.12114, lng: -1.71129, zoom: 18 };
};
//ACCESSORS
/**
* @return The HTML element for this view
*/
Layers.prototype.get = function() {
var element = $("<div/>");
if(this._styles) {
element.append("<h2>Style</h2>");
var styles = $("<div id=\"side-content-layers-styles\"></div>");
//Read each meta style
for(var s=0; s < this._styles.length; s++) {
var mcssStyle = this._styles[s].getStyles(
{
isSubject: function(subject) { return subject == "meta"; },
getParentObjects: function() { return []; }
},
{},
18
);
if(mcssStyle && mcssStyle.metaStyles && mcssStyle.metaStyles.default && mcssStyle.metaStyles.default.title) {
var img = (mcssStyle.pointStyles && mcssStyle.pointStyles.default && mcssStyle.pointStyles.default.icon_image) ?
/url\(\'(.+)\'\)/.exec(mcssStyle.pointStyles.default.icon_image)[1]
: "favicon.png";
styles.append($("<div class=\"side-content-layers-button style\"><img src=\"img/"+img+"\" /> "+mcssStyle.metaStyles.default.title.replace(/\'/g, "")+"</div>"));
}
}
element.append(styles);
}
if(this._bases) {
element.append("<h2>Background</h2>");
var bases = $("<div id=\"side-content-layers-bases\"></div>");
for(var b in this._bases) {
var url = this._bases[b].options.URL
.replace(/\{s\}/, this._bases[b].options.subdomains[0])
.replace(/\{z\}/, this._coords.zoom)
.replace(/\{x\}/, parseInt(Math.floor((this._coords.lng + 180) / 360 * (1<<this._coords.zoom))))
.replace(/\{y\}/, parseInt(Math.floor( (1 - Math.log(Math.tan(this._coords.lat.toRad()) + 1 / Math.cos(this._coords.lat.toRad())) / Math.PI) / 2 * (1<<this._coords.zoom) )));
bases.append($("<div class=\"side-content-layers-button base\"><img src=\""+url+"\" /><span>"+b+"</span></div>"));
}
element.append(bases);
}
return element;
};
//MODIFIERS
/**
* Change the layers
*/
Layers.prototype.set = function(baselayers, mapstyles) {
this._bases = baselayers;
this._styles = mapstyles;
};
/**
* Change the coordinates
*/
Layers.prototype.setCoordinates = function(lat, lng, zoom) {
this._coords = { lat: lat, lng: lng, zoom: zoom };
};
module.exports = Layers;
meta {
title: 'Default';
icon-image: url('favicon.png');
}
......@@ -12,7 +13,7 @@ meta {
font-size: 12;
font-weight: bold;
text-color: black;
text-offset: -12;
text-offset: 6; /** Half of the font-size **/
text: name;
}
......@@ -54,10 +55,14 @@ area[indoor=~/area|corridor/],
area[buildingpart=~/corridor|hall/],
area[room=~/corridor|hall|entry|gallery|collection|entrance/],
area[highway=~/pedestrian|footway|corridor/],
area[railway=platform],
area[public_transport=platform],
relation[type=multipolygon][indoor=~/area|corridor/],
relation[type=multipolygon][buildingpart=~/corridor|hall/],
relation[type=multipolygon][room=~/corridor|hall|entry|gallery|collection|entrance/],
relation[type=multipolygon][highway=~/pedestrian|footway|corridor/] {
relation[type=multipolygon][highway=~/pedestrian|footway|corridor/],
relation[type=multipolygon][railway=platform],
relation[type=multipolygon][public_transport=platform] {
fill-color: #EEEEEE;
fill-opacity: 1;
z-index: -6;
......@@ -97,7 +102,11 @@ relation[type=multipolygon][building:part=floor] {
/** No wall **/
area[indoor=area],
relation[type=multipolygon][indoor=area] {
area[railway=platform],
area[public_transport=platform],
relation[type=multipolygon][indoor=area],
relation[type=multipolygon][railway=platform],
relation[type=multipolygon][public_transport=platform] {
color: #AAAAAA;
opacity: 1;
width: 0.5;
......@@ -116,9 +125,9 @@ relation[type=multipolygon][indoor=area] {
* Room/area icons
*/
area[room],
area[area],
area[area][area!=yes],
relation[type=multipolygon][room],
relation[type=multipolygon][area] {
relation[type=multipolygon][area][area!=yes] {
icon-image-aliases: '"amphitheatre": "auditorium", "reception": "administration", "refectory": "restaurant", "checkroom": "locker"';
icon-width: 24;
icon-height: 24;
......@@ -130,8 +139,8 @@ relation[type=multipolygon][room] {
icon-image: url('room_$[room].png');
}
area[area],
relation[type=multipolygon][area] {
area[area][area!=yes],
relation[type=multipolygon][area][area!=yes] {
icon-image: url('room_$[area].png');
}
......@@ -314,3 +323,24 @@ line[conveying=~/yes|forward|backward|reversible/][highway=footway] {
width: 2;
linecap: none;
}
/****************************************************************************
* Railway
*/
way[railway=~/rail|subway|light_rail|monorail|narrow_gauge|tram/] {
color: #888888;
opacity: 1;
width: 10;
linecap: none;
dashes: 5,5;
}
*[railway=~/platform|subway_entrance|buffer_stop/] {
icon-image: url('railway_$[railway].png');
icon-width: 24;
icon-height: 24;
icon-opacity: 1;
}
......@@ -2,6 +2,7 @@
meta {
title: 'Details';
icon-image: url('icon_settings.png');
}
node, way {
......
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="OLU.css" />
<style>
#map-container {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map-container">
<div id="map"></div>
<div id="side"></div>
</div>
<script src="View_SideContent_LayersTest.js.bundle.js"></script>
</body>
</html>