summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--examples/full.html1
-rw-r--r--examples/indoor.html1
-rw-r--r--examples/zepler.html1
m---------resources/leaflet-indoor0
-rw-r--r--src/leaflet-soton.css129
-rw-r--r--src/leaflet-soton.js498
7 files changed, 150 insertions, 483 deletions
diff --git a/.gitmodules b/.gitmodules
index d6ad98a..662791d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -16,3 +16,6 @@
[submodule "resources/leaflet-hash"]
path = resources/leaflet-hash
url = https://github.com/mlevans/leaflet-hash.git
+[submodule "resources/leaflet-indoor"]
+ path = resources/leaflet-indoor
+ url = git@github.com:cbaines/leaflet-indoor.git
diff --git a/examples/full.html b/examples/full.html
index ed80cd5..cae1e87 100644
--- a/examples/full.html
+++ b/examples/full.html
@@ -27,6 +27,7 @@
<script src="../resources/leaflet-markercluster/dist/leaflet.markercluster.js"></script>
<script src="../resources/leaflet-locatecontrol/src/L.Control.Locate.js"></script>
<script src="../resources/leaflet-hash/leaflet-hash.js"></script>
+ <script src="../resources/leaflet-indoor/leaflet-indoor.js"></script>
<script src="../src/leaflet-soton.js"></script>
diff --git a/examples/indoor.html b/examples/indoor.html
index f94c252..47de9a2 100644
--- a/examples/indoor.html
+++ b/examples/indoor.html
@@ -22,6 +22,7 @@
<div id="map"></div>
<script src="../resources/leaflet/dist/leaflet-src.js"></script>
+ <script src="../resources/leaflet-indoor/leaflet-indoor.js"></script>
<script src="../src/leaflet-soton.js"></script>
diff --git a/examples/zepler.html b/examples/zepler.html
index 4caf762..0900992 100644
--- a/examples/zepler.html
+++ b/examples/zepler.html
@@ -24,6 +24,7 @@
<script src="../resources/leaflet/dist/leaflet.js"></script>
<script src="../resources/leaflet-markercluster/dist/leaflet.markercluster.js"></script>
+ <script src="../resources/leaflet-indoor/leaflet-indoor.js"></script>
<script src="../src/leaflet-soton.js"></script>
diff --git a/resources/leaflet-indoor b/resources/leaflet-indoor
new file mode 160000
+Subproject cb980fc85685334ac88d6cc8d2224d219b80006
diff --git a/src/leaflet-soton.css b/src/leaflet-soton.css
index a464a5f..af1ecda 100644
--- a/src/leaflet-soton.css
+++ b/src/leaflet-soton.css
@@ -56,135 +56,6 @@
}
-.ls-btn {
- display: inline-block;
- *display: inline;
- /* IE7 inline-block hack */
-
- *zoom: 1;
- padding: 4px 10px 4px;
- margin-bottom: 0;
- font-size: 13px;
- line-height: 18px;
- color: #333333;
- text-align: center;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
- vertical-align: middle;
- background-color: #f5f5f5;
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -ms-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: linear-gradient(top, #ffffff, #e6e6e6);
- background-repeat: repeat-x;
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#e6e6e6', GradientType=0);
- border-color: #e6e6e6 #e6e6e6 #bfbfbf;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
- border: 1px solid #cccccc;
- border-bottom-color: #b3b3b3;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
- cursor: pointer;
- *margin-left: .3em;
-}
-.ls-btn:hover,
-.ls-btn:active,
-.ls-btn.active,
-.ls-btn.disabled,
-.ls-btn[disabled] {
- background-color: #e6e6e6;
-}
-.ls-btn:active,
-.ls-btn.active {
- background-color: #cccccc \9;
-}
-.ls-btn:first-child {
- *margin-left: 0;
-}
-.ls-btn:hover {
- color: #333333;
- text-decoration: none;
- background-color: #e6e6e6;
- background-position: 0 -15px;
- -webkit-transition: background-position 0.1s linear;
- -moz-transition: background-position 0.1s linear;
- -ms-transition: background-position 0.1s linear;
- -o-transition: background-position 0.1s linear;
- transition: background-position 0.1s linear;
-}
-.ls-btn:focus {
- outline: thin dotted #333;
- outline: 5px auto -webkit-focus-ring-color;
- outline-offset: -2px;
-}
-.ls-btn.active,
-.ls-btn:active {
- background-image: none;
- -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
- background-color: #e6e6e6;
- background-color: #d9d9d9 \9;
- outline: 0;
-}
-
-.ls-btn-group .ls-btn {
- position: relative;
- float: left;
- margin-left: -1px;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- border-radius: 0;
-}
-.ls-btn-group .ls-btn:first-child {
- margin-left: 0;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- border-top-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-bottom-left-radius: 4px;
-}
-.ls-btn-group .ls-btn:last-child,
-.ls-btn-group .dropdown-toggle {
- -webkit-border-top-right-radius: 4px;
- -moz-border-radius-topright: 4px;
- border-top-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-bottomright: 4px;
- border-bottom-right-radius: 4px;
-}
-.ls-btn-group .ls-btn.large:first-child {
- margin-left: 0;
- -webkit-border-top-left-radius: 6px;
- -moz-border-radius-topleft: 6px;
- border-top-left-radius: 6px;
- -webkit-border-bottom-left-radius: 6px;
- -moz-border-radius-bottomleft: 6px;
- border-bottom-left-radius: 6px;
-}
-.ls-btn-group .ls-btn.large:last-child,
-.ls-btn-group .large.dropdown-toggle {
- -webkit-border-top-right-radius: 6px;
- -moz-border-radius-topright: 6px;
- border-top-right-radius: 6px;
- -webkit-border-bottom-right-radius: 6px;
- -moz-border-radius-bottomright: 6px;
- border-bottom-right-radius: 6px;
-}
-.ls-btn-group .ls-btn:hover,
-.ls-btn-group .ls-btn:focus,
-.ls-btn-group .ls-btn:active,
-.ls-btn-group .ls-btn.active {
- z-index: 2;
-}
-
.ls-nav {
margin-left: 0;
padding: 0;
diff --git a/src/leaflet-soton.js b/src/leaflet-soton.js
index f6ce069..7f84154 100644
--- a/src/leaflet-soton.js
+++ b/src/leaflet-soton.js
@@ -418,179 +418,182 @@ SELECT * WHERE {\
LS.getWorkstationData(function(workstationData) {
- // Adding .features means leaflet will
- // ignore those without a geometry
- map.indoorLayer = L.indoorLayer(data.buildingParts.features, {
- level: map._startLevel,
- style: function(feature) {
- var fill = 'white';
- if (feature.properties.buildingpart === 'corridor') {
- fill = '#169EC6';
- } else if (feature.properties.buildingpart === 'verticalpassage') {
- fill = '#0A485B';
- }
-
- return {
- fillColor: fill,
- weight: 1,
- color: '#666',
- fillOpacity: 1
- };
- },
- markerForFeature: function(part) {
- if (part.properties.buildingpart === "room") {
-
- var iconCoords = part.properties.center;
-
- if (part.properties.name === "The Bridge") {
- return L.marker(iconCoords, {icon: icons.theBridge});
- } else if (part.properties.name === "SUSU Shop") {
- return L.marker(iconCoords, {icon: icons.theSUSUShop});
- } else if (part.properties.name === "The Stag's") {
- return L.marker(iconCoords, {icon: icons.theStags});
- } else if (part.properties.name === "SUSU Cafe") {
- return L.marker(iconCoords, {icon: icons.theSUSUCafe});
+ if (options.indoor) {
+ // Adding .features means leaflet will
+ // ignore those without a geometry
+ map.indoorLayer = L.indoor(data.buildingParts.features, {
+ level: map._startLevel,
+ style: function(feature) {
+ var fill = 'white';
+ if (feature.properties.buildingpart === 'corridor') {
+ fill = '#169EC6';
+ } else if (feature.properties.buildingpart === 'verticalpassage') {
+ fill = '#0A485B';
}
- var partWorkstation = null;
+ return {
+ fillColor: fill,
+ weight: 1,
+ color: '#666',
+ fillOpacity: 1
+ };
+ },
+ markerForFeature: function(part) {
+ if (part.properties.buildingpart === "room") {
+
+ var iconCoords = part.properties.center;
+
+ if (part.properties.name === "The Bridge") {
+ return L.marker(iconCoords, {icon: icons.theBridge});
+ } else if (part.properties.name === "SUSU Shop") {
+ return L.marker(iconCoords, {icon: icons.theSUSUShop});
+ } else if (part.properties.name === "The Stag's") {
+ return L.marker(iconCoords, {icon: icons.theStags});
+ } else if (part.properties.name === "SUSU Cafe") {
+ return L.marker(iconCoords, {icon: icons.theSUSUCafe});
+ }
- if ('contents' in part.properties) {
- part.properties.contents.forEach(function(feature) {
- if (feature.subject === "http://id.southampton.ac.uk/point-of-interest-category/iSolutions-Workstations") {
- partWorkstation = feature;
- }
- });
- }
+ var partWorkstation = null;
- if (part.properties.amenity === "toilets") {
- if ("male" in part.properties) {
- return L.marker(iconCoords, {icon: icons.toiletsMale});
- } else if ("female" in part.properties) {
- return L.marker(iconCoords, {icon: icons.toiletsFemale});
- } else if ("unisex" in part.properties) {
- return L.marker(iconCoords, {icon: icons.toiletsUnisex});
- } // TODO: Disabled
- }
+ if ('contents' in part.properties) {
+ part.properties.contents.forEach(function(feature) {
+ if (feature.subject === "http://id.southampton.ac.uk/point-of-interest-category/iSolutions-Workstations") {
+ partWorkstation = feature;
+ }
+ });
+ }
- var content;
+ if (part.properties.amenity === "toilets") {
+ if ("male" in part.properties) {
+ return L.marker(iconCoords, {icon: icons.toiletsMale});
+ } else if ("female" in part.properties) {
+ return L.marker(iconCoords, {icon: icons.toiletsFemale});
+ } else if ("unisex" in part.properties) {
+ return L.marker(iconCoords, {icon: icons.toiletsUnisex});
+ } // TODO: Disabled
+ }
- if ("name" in part.properties && "ref" in part.properties) {
- content = part.properties.name + " (" + part.properties.ref + ")";
- } else if ("ref" in part.properties) {
- content = "Room " + part.properties.ref;
- } else if ("name" in part.properties) {
- content = part.properties.name;
- } else {
- return;
- }
+ var content;
- if (partWorkstation) {
- if (partWorkstation.feature in workstationData) {
- var state = workstationData[partWorkstation.feature];
+ if ("name" in part.properties && "ref" in part.properties) {
+ content = part.properties.name + " (" + part.properties.ref + ")";
+ } else if ("ref" in part.properties) {
+ content = "Room " + part.properties.ref;
+ } else if ("name" in part.properties) {
+ content = part.properties.name;
+ } else {
+ return;
+ }
- var closed = (state.status.indexOf("closed") !== -1)
+ if (partWorkstation) {
+ if (partWorkstation.feature in workstationData) {
+ var state = workstationData[partWorkstation.feature];
- var image;
- var workstationIcon;
+ var closed = (state.status.indexOf("closed") !== -1)
- if (!closed) {
- image = 'workstation-group.png';
- workstationIcon = '<div class="ls-workstationicon" style="margin-left: auto; margin-right: auto; background-image: url(' + LS.imagePath + image + ')">';
- } else {
- image = 'workstation-closed.png';
- workstationIcon = '<div class="ls-workstationicon-small" style="margin-left: auto; margin-right: auto; background-image: url(' + LS.imagePath + image + ')">';
- }
+ var image;
+ var workstationIcon;
- if (!closed) {
- workstationIcon += '<div style="padding-left: 26px;">';
+ if (!closed) {
+ image = 'workstation-group.png';
+ workstationIcon = '<div class="ls-workstationicon" style="margin-left: auto; margin-right: auto; background-image: url(' + LS.imagePath + image + ')">';
+ } else {
+ image = 'workstation-closed.png';
+ workstationIcon = '<div class="ls-workstationicon-small" style="margin-left: auto; margin-right: auto; background-image: url(' + LS.imagePath + image + ')">';
+ }
- var freeSeats = state.free_seats;
- workstationIcon += freeSeats + "</div>";
- }
+ if (!closed) {
+ workstationIcon += '<div style="padding-left: 26px;">';
- workstationIcon += '</div>';
+ var freeSeats = state.free_seats;
+ workstationIcon += freeSeats + "</div>";
+ }
- content = workstationIcon + content;
- } else {
- var workstationIcon = '<div style="margin-left: auto; margin-right: auto; width: 32px; height: 32px; background-image: url(' + LS.imagePath + 'workstation.png' + ')"></div>';
+ workstationIcon += '</div>';
+
+ content = workstationIcon + content;
+ } else {
+ var workstationIcon = '<div style="margin-left: auto; margin-right: auto; width: 32px; height: 32px; background-image: url(' + LS.imagePath + 'workstation.png' + ')"></div>';
- content = workstationIcon + content;
+ content = workstationIcon + content;
+ }
}
- }
- var myIcon = L.divIcon({
- className: 'ls-room-marker',
- html: content,
- iconSize: new L.Point(100, 30),
- iconAnchor: new L.Point(50, 15)
- });
+ var myIcon = L.divIcon({
+ className: 'ls-room-marker',
+ html: content,
+ iconSize: new L.Point(100, 30),
+ iconAnchor: new L.Point(50, 15)
+ });
- var marker = L.marker(iconCoords, {icon: myIcon});
+ var marker = L.marker(iconCoords, {icon: myIcon});
- return marker;
- }
- },
- onEachFeature: function(feature, layer) {
- if (feature.properties.buildingpart === "corridor") {
- return; // No popup for corridors yet
- }
+ return marker;
+ }
+ },
+ onEachFeature: function(feature, layer) {
+ if (feature.properties.buildingpart === "corridor") {
+ return; // No popup for corridors yet
+ }
- layer.on('click', function(e) {
- var content;
- var popupOptions = {};
+ layer.on('click', function(e) {
+ var content;
+ var popupOptions = {};
- // When the feature is clicked on
- if ("buildingpart" in feature.properties) {
- if (feature.properties.buildingpart === "room") {
- content = roomPopupTemplate(feature.properties);
- } else if (feature.properties.buildingpart === "verticalpassage") {
- content = verticalPassagePopupTemplate(feature.properties);
+ // When the feature is clicked on
+ if ("buildingpart" in feature.properties) {
+ if (feature.properties.buildingpart === "room") {
+ content = roomPopupTemplate(feature.properties);
+ } else if (feature.properties.buildingpart === "verticalpassage") {
+ content = verticalPassagePopupTemplate(feature.properties);
+ }
+ } else { // Assume that it is a printer
+ // TODO: Use different icons where appropriate
+ popupOptions.offset = icons.vendingHotDrinks.options.popupAnchor;
+
+ if ('vending' in feature.properties) {
+ content = vendingPopupTemplate(feature.properties);
+ } else {
+ content = printerPopupTemplate(feature.properties);
+ }
}
- } else { // Assume that it is a printer
- // TODO: Use different icons where appropriate
- popupOptions.offset = icons.vendingHotDrinks.options.popupAnchor;
- if ('vending' in feature.properties) {
- content = vendingPopupTemplate(feature.properties);
+ showPopup(map, content, e.latlng, popupOptions);
+ });
+ },
+ pointToLayer: function (feature, latlng) {
+ var icon;
+
+ if ('vending' in feature.properties) {
+ if (feature.properties.vending === 'drinks') {
+ icon = icons.vendingHotDrinks;
+ } else if (feature.properties.vending === 'sweets') {
+ icon = icons.vendingSweets;
} else {
- content = printerPopupTemplate(feature.properties);
+ console.warn("Unrecognired vending " + feature.properties.vending);
}
- }
-
- showPopup(map, content, e.latlng, popupOptions);
- });
- },
- pointToLayer: function (feature, latlng) {
- var icon;
-
- if ('vending' in feature.properties) {
- if (feature.properties.vending === 'drinks') {
- icon = icons.vendingHotDrinks;
- } else if (feature.properties.vending === 'sweets') {
- icon = icons.vendingSweets;
} else {
- console.warn("Unrecognired vending " + feature.properties.vending);
+ icon = icons.printer;
}
- } else {
- icon = icons.printer;
+
+ return L.marker(latlng, {icon: icon});
}
+ });
- return L.marker(latlng, {icon: icon});
- }
- });
+ map.indoorLayer.addData(data.buildingFeatures);
- map.indoorLayer.addData(data.buildingFeatures);
+ map.levelControl = L.Control.level({
+ levels: map.indoorLayer.getLevels(),
+ level: map._startLevel
+ });
- map.levelControl = L.Control.level({
- levels: map.indoorLayer.getLevels(),
- level: map._startLevel
- });
+ map.levelControl.addEventListener("levelchange", map.indoorLayer.setLevel, map.indoorLayer);
- map.levelControl.addEventListener("levelchange", map.indoorLayer.setLevel, map.indoorLayer);
+ map.levelControl.on("levelchange", function(e) {
+ map.fireEvent("levelchange", e);
+ });
- map.levelControl.on("levelchange", function(e) {
- map.fireEvent("levelchange", e);
- });
+ }
var workstationMarkerLayer;
if (options.workstations) {
@@ -1642,219 +1645,6 @@ SELECT * WHERE {\
}
})();
-L.Control.Level = L.Control.extend({
- includes: L.Mixin.Events,
-
- options: {
- position: 'bottomright',
- parseLevel: function(level) {
- return parseInt(level, 10);
- }
- },
-
- initialize: function(options) {
- L.setOptions(this, options);
-
- this._map = null;
- this._buttons = {};
- this._listeners = [];
- this._level = options.level;
-
- this.addEventListener("levelchange", this._levelChange, this);
- },
- onAdd: function(map) {
- var div = L.DomUtil.create('div', 'ls-levelselector');
-
- var btnGroup = L.DomUtil.create('div', 'ls-btn-group', div);
-
- var buttons = this._buttons;
- var activeLevel = this._level;
- var self = this;
-
- this.options.levels.forEach(function(level) {
- var cls = 'ls-btn';
-
- var levelNum = self.options.parseLevel(level);
-
- if (level === activeLevel || levelNum === activeLevel)
- cls += ' active';
-
- var levelBtn = L.DomUtil.create('button', cls, btnGroup);
-
- levelBtn.appendChild(levelBtn.ownerDocument.createTextNode(level));
-
- levelBtn.onclick = function() {
- self.setLevel(level);
- };
-
- buttons[level] = levelBtn;
- });
-
- return div;
- },
- _levelChange: function(e) {
- // Probably won't work in some browsers, see
- // https://developer.mozilla.org/en-US/docs/Web/API/element.classList
-
- if (this._map !== null) {
- this._buttons[e.oldLevel].classList.remove('active');
- this._buttons[e.newLevel].classList.add('active');
- }
- },
- setLevel: function(level) {
-
- if (level === this._level)
- return;
-
- var oldLevel = this._level;
- this._level = level;
-
- this.fireEvent("levelchange", {
- oldLevel: oldLevel,
- newLevel: level
- });
- },
- getLevel: function() {
- return this._level;
- }
-});
-
-L.Control.level = function (options) {
- return new L.Control.Level(options);
-};
-
-/**
- * A layer that will display indoor data
- *
- * addData takes a GeoJSON feature collection, each feature must have a level
- * property that indicates the level. If the level is a string, some function
- * will be used to rank the levels.
- *
- * getLevels can be called to get the array of levels that are present.
- *
- *
- */
-
-L.IndoorLayer = L.Class.extend({
-
- initialize: function(data, options) {
- L.setOptions(this, options);
-
- var onEachFeature = options.onEachFeature;
- var layers = this._layers = {};
- this._map = null;
- if ("level" in options) {
- this._level = options.level;
- } else {
- this._level = null;
- }
-
- this.options.onEachFeature = function(feature, layer) {
-
- onEachFeature(feature, layer);
-
- var marker = options.markerForFeature(feature);
- if (typeof(marker) !== 'undefined') {
- marker.on('click', function(e) {
- layer.fire('click', e);
- });
-
- layers[feature.properties.level].addLayer(marker);
- }
- };
-
- this.addData(data);
- },
- addTo: function (map) {
- map.addLayer(this);
- return this;
- },
- onAdd: function (map) {
- this._map = map;
-
- if (this._level === null) {
- var levels = this.getLevels();
-
- if (levels.length !== 0) {
- this._level = levels[0];
- }
- }
-
- this._map.addLayer(this._layers[this._level]);
- },
- onRemove: function (map) {
- this._map.removeLayer(this._layers[this._level]);
- this._map = null;
- },
- addData: function(data) {
- var layers = this._layers;
-
- var options = this.options;
-
- var features = L.Util.isArray(data) ? data : data.features;
-
- features.forEach(function (part) {
- var level = part.properties.level;
- var layer;
-
- if (typeof level === 'undefined')
- return;
-
- if (!("geometry" in part)) {
- return;
- }
-
- if (L.Util.isArray(level)) {
- level.forEach(function(level) {
- if (level in layers) {
- layer = layers[level];
- } else {
- layer = layers[level] = L.geoJson({ type: "FeatureCollection", features: [] }, options);
- }
-
- layer.addData(part);
- });
- } else {
- if (level in layers) {
- layer = layers[level];
- } else {
- layer = layers[level] = L.geoJson({ type: "FeatureCollection", features: [] }, options);
- }
-
- layer.addData(part);
- }
- });
- },
- getLevels: function() {
- return Object.keys(this._layers);
- },
- getLevel: function() {
- return this._level;
- },
- setLevel: function(level) {
- if (typeof(level) === 'object') {
- level = level.newLevel;
- }
-
- if (this._level === level)
- return;
-
- var oldLayer = this._layers[this._level];
- var layer = this._layers[level];
-
- if (this._map !== null) {
- this._map.removeLayer(oldLayer);
- this._map.addLayer(layer);
- }
-
- this._level = level;
- }
-});
-
-L.indoorLayer = function(data, options) {
- return new L.IndoorLayer(data, options);
-};
-
L.SelectiveVisibilityLayer = L.Class.extend({
_layers: {},
@@ -1901,7 +1691,7 @@ L.SelectiveVisibilityLayer = L.Class.extend({
});
L.SelectiveVisibilityLayer = function(data, options) {
- return new L.IndoorLayer(data, options);
+ return new L.Indoor(data, options);
};
// forEach compatability
if (!Array.prototype.forEach) {