Skip to content

Instantly share code, notes, and snippets.

@hanleyhansen
Last active December 20, 2015 00:09
Show Gist options
  • Save hanleyhansen/cbaababbc480633881fe to your computer and use it in GitHub Desktop.
Save hanleyhansen/cbaababbc480633881fe to your computer and use it in GitHub Desktop.
JS Fundamentals
var sort_by = function(field, reverse, primer){
var key = function (x) {return primer ? primer(x[field]) : x[field]};
return function (a,b) {
var A = key(a), B = key(b);
return ((A < B) ? -1 : (A > B) ? +1 : 0) * [-1,1][+!!reverse];
}
}
$('.mapsearch').typeahead({
minLength: 2,
source: function (seed, process) {
api.Assets.mapsearch(seed, function (data) {
var s = [];
_.each(data, function (item) {
s.push(JSON.stringify(item));
});
process(s);
});
},
highlighter: function (data) {
var item = JSON.parse(data);
item.t = item.rectype === "room" ? "R" : "A";
return Mustache.render('<a style="background: transparent;" ' +
'onclick="map.showItemOnMap({{id}},\'{{rectype}}\');"' +
'>[{{t}}] {{name}}</a> &nbsp;&nbsp;<a style="background: transparent;" href="#{{rectype}}-details?id={{id}}"><i class="icon-file"/></a>', item);
},
updater: function (data) {
var item = JSON.parse(data);
map.showItemOnMap(item.id, item.rectype);
console.log('SHOWING ON MAP');
}
});
var resizeCalendar = function (e) {
loadCalendar();
};
var loadMyTickets = function() {
api.Tickets.getMyTickets(function(data){
$('#myTickets').empty();
_.each(data, function(d,index){
if (index < 10)
$('#myTickets').append(Mustache.render("<li><b>[Ticket# {{id}}]</b> - {{title}}</li>",d));
});
});
};
var loadMyAssignments = function() {
api.Tickets.getTickets(function(data){
$('#myAssignments').empty();
_.each(data, function(d,index){
if (index < 10)
$('#myAssignments').append(Mustache.render("<li><b>[Ticket# {{id}}]</b> - {{title}}</li>",d));
});
}, {
assignees: '%' + site.currentuser.username + '%'
});
};
var loadAreas = function() {
api.Areas.getAreas(function(data){
$('#areas').empty();
_.each(data.sort(sort_by('name', true, function(a){return a.toUpperCase()})), function(d,index){
$('#areas').append(Mustache.render("<option id='{{id}}'>{{name}}</option>",d));
});
});
};
var loadCategories = function() {
$('#categories').empty();
_.each(api.Assets.categories().sort(sort_by('name', true, function(a){return a.toUpperCase()})), function(d,index){
$('#categories').append(Mustache.render("<option id='{{id}}'>{{name}}</option>",d));
});
};
var loadCalendar = function () {
api.Events.currentMonth(function (data) {
$('#calendar').empty();
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
weekMode: 'liquid',
editable: true,
events: data,
eventClick: function (calEvent, jsEvent, view) {
if (calEvent.type === 'maintenance') window.location.hash = '#ticket?title=' + calEvent.title + "&relations=" + calEvent.AssetId;
else window.location.hash = '#ticket?id=' + calEvent.TicketId;
}
});
$('#page').show();
});
}
var date = new Date();
var d = date.getDate();
var m = date.getMonth();
var y = date.getFullYear();
resizeCalendar();
loadMyTickets();
loadMyAssignments();
loadAreas();
loadCategories();
$('mapcontrols').hide();
$('.navbar-fixed-top li').removeClass('active');
$("li.dashboard").addClass('active');
var quickJump = function () {
var cat = $('#categories').children(":selected").attr("id");
var area = $('#areas').children(":selected").attr("id");
window.location = "/#map?area=" + area + "&x=0&y=0&z=3&c=" + cat;
}
var newAsset = function () {
window.location = "/#map";
setTimeout(map.startnewasset(), 2000);
}
var newTicket = function () {
window.location = "/#map";
setTimeout(map.startnewticket(), 2000);
}
/******************************************************************\
** JCAH Commissioning Mapping Library **
*****************************************
History:
2013-01-25 AKANIESKI: Initial Creation and Migration from KineticJS to LeafletJS
/******************************************************************/
// Begin by Instanciating Mapping namespace
var map = {
accordionTemplate: $('#accordionTemplate').html(),
currentzone: null,
currentshape: null,
currentroom: null,
currentasset: null,
root: null,
assets: null,
tags: null,
tiles: null,
currentcategory: null,
currentassets: null,
moving: false,
movingmarker: null,
currentPopup: null
};
map.roomIcon = L.icon({
iconUrl: 'images/room.png',
iconSize: [22, 22],
// size of the icon
iconAnchor: [15, 13],
// point of the icon which will correspond to marker's location
popupAnchor: [0, 2],
// point from which the popup should open relative to the iconAnchor
labelAnchor: [0, 0]
});
map.warningIcon = L.icon({
iconUrl: 'images/warning-icon.png',
iconSize: [22, 22],
// size of the icon
iconAnchor: [15, 13],
// point of the icon which will correspond to marker's location
popupAnchor: [0, 2],
// point from which the popup should open relative to the iconAnchor
labelAnchor: [0, 0]
});
map.jumpIcon = L.icon({
iconUrl: 'images/jump.png',
iconSize: [34, 34],
// size of the icon
iconAnchor: [23, 21],
// point of the icon which will correspond to marker's location
popupAnchor: [0, 2],
// point from which the popup should open relative to the iconAnchor
labelAnchor: [0, 0]
});
map.emergencyMarker = new L.Icon.Default();
map.emergencyMarker.options.iconUrl = 'javascripts/images/emergency-marker-icon.png';
map.defaultMarker = L.icon({
iconUrl: 'javascripts/images/marker-icon.png'
});
page.loading = true;
map.getMarker = function (assetid) {
for (var marker in map.assets._layers) {
if (map.assets._layers[marker].dataitem && map.assets._layers[marker].dataitem.id === assetid) {
return map.assets._layers[marker];
}
}
if (map.relationLayer && map.relationLayer._layers) {
for (var marker in map.relationLayer._layers) {
if (map.relationLayer._layers[marker].dataitem && map.relationLayer._layers[marker].dataitem.id === assetid) {
return map.relationLayer._layers[marker];
}
}
}
return null;
}
map.startnewticket = function () {
bootbox.dialog('Can you place this ticket on the map?', [{
"label": "Yes I can",
"class": "btn-primary",
"callback": function () {
$('body').css({
'cursor': 'pointer'
});
map.toggleCancel('Cancel New Ticket', function () {
map.toggleCancel();
map.root.off('click');
$('body').css({
'cursor': 'default'
});
});
map.root.on('click', function (e) {
bootbox.confirm('Create Ticket at this location?', function (yes) {
if (yes) {
bootbox.hideAll();
map.toggleCancel();
site.returnUrl = '#map?area=' + map.currentarea.id + '&x=' + e.latlng.lat + '&y=' + e.latlng.lng + '&z=5';
window.location.hash = '#ticket?AreaId=' + map.currentarea.id + '&x=' + e.latlng.lat + '&y=' + e.latlng.lng;
}
});
});
}
}, {
"label": "No I can't",
"class": "btn",
"callback": function () {
window.location.hash = '#ticket';
}
}]);
}
$('.mapsearch').typeahead({
minLength: 2,
source: function (seed, process) {
api.Assets.mapsearch(seed, function (data) {
var s = [];
_.each(data, function (item) {
s.push(JSON.stringify(item));
});
process(s);
});
},
highlighter: function (data) {
var item = JSON.parse(data);
item.t = item.rectype === "room" ? "R" : "A";
return Mustache.render('<a style="background: transparent;" ' +
'onclick="map.showItemOnMap({{id}},\'{{rectype}}\');"' +
'>[{{t}}] {{name}}</a> &nbsp;&nbsp;<a style="background: transparent;" href="#{{rectype}}-details?id={{id}}"><i class="icon-file"/></a>', item);
},
updater: function (data) {
var item = JSON.parse(data);
map.showItemOnMap(item.id, item.rectype);
console.log('SHOWING ON MAP');
}
});
map.showRoomOnMap = function (item) {
if (map.currentarea.id != item.AreaId) {
map.currentarea = api.Areas.getArea(item.AreaId);
map.loadTiles(map.currentarea.id);
}
map.root.panTo([item.x, item.y]);
map.root.setZoom(5);
var tag = map.getRoomTag(item.id);
if (tag) tag.openPopup();
};
map.showItemOnMap = function (id, rectype) {
console.log({
id: id,
rectype: rectype
});
var item = rectype === 'room' ? api.Rooms.getRoom(id) : api.Assets.getAsset(id);
if (rectype === 'asset' && !item.hidden) {
window.location.hash = '#map?area=' + item.AreaId + '&x=' + item.x + '&y=' + item.y + '&z=5&c=' + item.category;
} else if (item.hidden) {
window.location = '#asset-details?id=' + item.id;
}
if (rectype === 'room') {
var jump = function(){
map.root.panTo([item.x, item.y]);
map.root.setZoom(5);
var tag = map.getRoomTag(item.id);
if (tag) tag.openPopup();
};
if (map.currentarea.id != item.AreaId) {
map.currentarea = api.Areas.getArea(item.AreaId);
map.loadTiles(map.currentarea.id, false, jump);
} else {
jump();
}
}
};
map.changeUnderlay = function(cat) {
map.currentcategory = cat;
$.sidr('close', 'map-controls');
$('#modals').append($('#underlay-change').html());
$('.upload-cancel').click(function(){
$('.modal-upload').remove();
$('.modal-backdrop').remove();
});
var cont = function(){
site.updateLoading(1);
$('.modal-upload').hide();
$('.modal-backdrop').hide();
$('.upload').attr('disabled','disabled');
var rmap = {
AreaId: map.currentarea.id,
category: map.currentcategory,
file: ""
};
if (document.getElementById('category-map').files.length > 0) {
var file = document.getElementById('category-map').files[0];
rmap.file = file.name.replace('.png', '');
var reader = new FileReader();
reader.onload = function(e) {
//alert(this.result.length);
// Save Binary String as Image
$.ajax({
url: '/uploadtiles/' + map.currentarea.id + (map.currentcategory === -1 ? '' : '/' + map.currentcategory),
type: 'POST',
data: JSON.stringify({
filename: file.name,
data: this.result,
category: map.currentcategory,
AreaId: map.currentarea.id
}),
async: true,
contentType: 'application/json',
failure: function(res) {
site.updateLoading(-1);
$('.modal-upload').remove();
$('.modal-backdrop').remove();
},
success: function(res) {
site.updateLoading(-1);
$('.modal-upload').remove();
$('.modal-backdrop').remove();
}
});
};
reader.readAsBinaryString(file, "UTF-8");
}
api.Areas.setMap(rmap);
map.loadTiles(map.currentarea.id);
$('.upload').removeAttr('disabled');
};
$('.upload').click(cont);
}
map.showAreaDetails = function(area) {
if (!area || area === '') area = map.currentarea;
else map.currentarea = area;
$("<div class='' id='tempdiv'></div>").load('area-details.html', function() {
$('#tempdiv').bindall();
}).appendTo($('body')).dialog({
height: 480,
width: 640,
draggable: false,
title: area.name,
modal: true,
dialogClass: 'modalshadow',
close: function() {
$(this).dialog('destroy').remove();
},
buttons: {
"Save": function() {
area = api.Areas.setArea(area);
$('#tempdiv').bindall();
}
}
});
}
map.getRoomTag = function(roomid) {
if (!roomid || !map.roomTags) return null;
for (var marker in map.roomTags._layers) {
if (map.roomTags._layers[marker].dataitem && map.roomTags._layers[marker].dataitem.id && map.roomTags._layers[marker].dataitem.id.toString() === roomid.toString()) {
return map.roomTags._layers[marker];
}
}
return null;
}
map.getAssetTag = function(assetid) {
if (!assetid || !map.assets) return null;
for (var marker in map.assets._layers) {
if (map.assets._layers[marker].dataitem && map.assets._layers[marker].dataitem.id && map.assets._layers[marker].dataitem.id.toString() === assetid.toString()) {
return map.assets._layers[marker];
}
}
return null;
}
map.toggleCancel = function(text, cb){
if($('#mapcancel').hasClass('hide')){
$('#mapcancel').text(text);
$('#mapcancel').removeClass('hide');
$('#mapcancel').on('click', cb);
} else {
$('#mapcancel').addClass('hide');;
$('#mapcancel').off('click');
}
}
map.duplicate = function(id, children) {
var marker = map.getMarker(id);
if (map.currentPopup != null) map.currentPopup._source.closePopup();
map.currentasset = api.Assets.getAsset(id);
$('body').css({
'cursor': 'pointer'
});
map.toggleCancel('Cancel Duplicate Operation', function(){
map.root.off('click');
map.toggleCancel();
$('body').css({
'cursor': 'default'
});
});
map.root.off('click');
map.root.on('click', function(e) {
bootbox.confirm("Place asset here?", function(yes){
if(yes){
bootbox.hideAll();
map.toggleCancel();
var newasset = api.Assets.duplicate(map.currentasset.id, e.latlng.lat, e.latlng.lng, children);
//alert('old flr: '+ newasset.AreaId + " new flr: "+ map.currentarea.id);
if (newasset.AreaId != map.currentarea.id) {
//alert('different floor');
newasset.AreaId = map.currentarea.id;
newasset.RoomId = null;
api.Assets.setAsset(newasset);
}
map.root.off('click');
$('body').css({
'cursor': 'default'
});
map.loadVisibleAssets();
var newmarker = map.getMarker(newasset.id);
if (newmarker) newmarker.openPopup();
}
});
});
}
map.beginmove = function(id) {
var marker = map.getMarker(id);
if (map.currentPopup != null) map.currentPopup._source.closePopup();
map.currentasset = api.Assets.getAsset(id);
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.toggleCancel('Cancel Moving Operation', function(){
map.toggleCancel();
map.root.off('click');
$('body').css({
'cursor': 'default'
});
});
map.root.on('click', function(e) {
bootbox.confirm('Move asset to new location?', function(yes){
if (yes) {
bootbox.hideAll();
map.toggleCancel();
var areachanged = false;
if (map.currentasset.AreaId != map.currentarea.id) {
areachanged = true;
map.currentasset.AreaId = map.currentarea.id;
} else {
var marker = map.getMarker(id);
marker.setLatLng(e.latlng);
marker.update();
}
map.currentasset.x = e.latlng.lat;
map.currentasset.y = e.latlng.lng;
api.Assets.setAsset(map.currentasset);
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
if (areachanged) map.loadVisibleAssets();
}
});
});
}
var temproom;
var newRoomTagInProgress = false;
map.startPlaceTag = function(roomid) {
if (!newRoomTagInProgress) {
temproom = null;
if (!roomid) {
newRoomTagInProgress = true;
temproom = api.Rooms.build();
temproom.AreaId = map.currentarea.id;
temproom.uniqueid = prompt('Enter a Room Number that follows the standard naming convention (ie. \'S2-11\'):');
temproom.name = prompt('Enter a \"Friendly\" Room Name thats easy to understand (ie. \'Admin Office\'):');
} else {
temproom = api.Rooms.getRoom(roomid);
}
alert('Now select a location on the map to place this room tag');
var tag = map.getRoomTag(roomid);
$('#dialog-roomtag').dialog('close');
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.root.on('click', function(e) {
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
temproom.x = e.latlng.lat;
temproom.y = e.latlng.lng;
temproom = api.Rooms.setRoom(temproom);
newRoomTagInProgress = false;
if (!tag) {
tag = L.marker([temproom.x, temproom.y], {
title: temproom.name + " - " + temproom.uniqueid,
icon: map.roomIcon
}).bindPopup(map.getRoomTagHtml(temproom), {
maxWidth: 300,
minWidth: 300,
autoPan: false
}).bindLabel(temproom.name && temproom.name.length > 0 ? temproom.name : temproom.uniqueid, {
noHide: true
});
tag.dataitem = temproom;
map.roomTags.addLayer(tag);
tag.showLabel();
}
tag.setLatLng(e.latlng);
tag.update();
map.loadVisibleRoomTags();
});
}
}
map.zoomToRoom = function(roomid) {}
map.showRoomTags = function() {
$("<div id='dialog-roomtag'></div>").load('roomtags.html', function() {
$.getScript('javascripts/roomtags.js');
}).appendTo($('body')).dialog({
height: 200,
width: 300,
title: "Room Tags",
modal: true,
dialogClass: 'modalshadow',
close: function() {
$(this).dialog('destroy').remove();
}
});
}
map.jumpToArea = function(areaid, parentX, parentY) {
var temp1 = [];
var temp2 = [];
$.each(map.relatedIconsInCurrentArea, function(index, marker) {
//marker['oldhtml'] = marker._popup._content;
marker._popup.setContent(map.getJumpHtml(marker.dataitem.AreaId));
marker.setIcon(map.jumpIcon);
marker.off('click', map.clearRelationLayer);
map.assets.removeLayer(marker);
map.relationLayer.addLayer(marker);
temp1.push(marker);
});
$.each(map.relatedIconsInOtherAreas, function(index, marker) {
//marker['oldhtml'] = marker._popup._content;
marker._popup.setContent(map.getAssetPopupHtml(marker.dataitem));
marker.setIcon(new L.Icon.Default());
marker.on('click', map.clearRelationLayer);
map.relationLayer.removeLayer(marker);
map.assets.addLayer(marker);
temp2.push(marker);
});
map.relatedIconsInCurrentArea = temp2;
map.relatedIconsInOtherAreas = temp1;
map.loadTiles(areaid, true);
}
map.relatedIconsInOtherAreas = [];
map.relatedIconsInCurrentArea = [];
map.getJumpHtml = function(areaid, parentX, parentY) {
var otherArea = api.Areas.getArea(areaid);
var html = "<h4>%name%</h4>" + "<ul class='nav'>" + "<li><a onclick='map.jumpToArea(" + areaid + "," + parentX + "," + parentY + ");'>Go To Area</a></li>" + "</ul>";
return substitute(html, otherArea);
}
map.clearRelationLayer = function() {
if (map.relationLayer) {
map.root.removeLayer(map.relationLayer);
map.relatedIconsInOtherAreas = [];
map.relatedIconsInCurrentArea = [];
}
};
map.paintingRelations = false;
map.relationCount = 0;
map.startShowRelations = function(id){
if (map.relationLayer && !map.paintingRelations) {
map.relationLayer.clearLayers();
map.root.addLayer(map.relationLayer);
map.paintingRelations = true;
map.relationOrigin = id;
} else if (!map.paintingRelations) {
map.relationLayer = new L.LayerGroup();
map.root.addLayer(map.relationLayer);
map.paintingRelations = true;
map.relationOrigin = id;
}
site.loadingcount = 0;
map.showRelations(id);
}
map.startShowParentRelations = function(id){
if (map.relationLayer && !map.paintingRelations) {
map.relationLayer.clearLayers();
map.root.addLayer(map.relationLayer);
map.paintingRelations = true;
map.relationOrigin = id;
} else if (!map.paintingRelations) {
map.relationLayer = new L.LayerGroup();
map.root.addLayer(map.relationLayer);
map.paintingRelations = true;
map.relationOrigin = id;
}
site.loadingcount = 0;
map.showParentRelations(id);
}
map.showRelations = function(id) {
site.updateLoading(1);
var parent = api.Assets.getAsset(id, function(parent){
//site.updateLoading(1);
api.Assets.getChildRelations(id, function(relations){
if (parent.hidden != 1 && parent.hidden != true) map.relatedIconsInCurrentArea.push(map.getMarker(parent.id));
if (!relations || relations.length === 0){
site.updateLoading(-1);
} else {
$.each(relations, function(k, v) {
if (v.AssetB.AreaId != parent.AreaId) {
// Child is on a different map -> Add a jump to icon
var icon = L.marker(new L.LatLng(v.AssetB.x, v.AssetB.y), {
icon: map.jumpIcon
}).bindPopup(map.getJumpHtml(v.AssetB.AreaId));
icon.dataitem = v.AssetB;
if (v.AssetB.hidden != 1 && v.AssetB.hidden != true) map.relatedIconsInOtherAreas.push(icon);
map.relationLayer.addLayer(icon);
} else {
if (v.AssetB.hidden != 1 && v.AssetB.hidden != true) map.relatedIconsInCurrentArea.push(map.getMarker(v.Asset_B));
}
var line = L.polyline([new L.LatLng(parent.x, parent.y), new L.LatLng(v.AssetB.x, v.AssetB.y)], {
color: 'green'
});
map.relationLayer.addLayer(line);
// Possibly make a recursive call to display the entire family tree of children
map.showRelations(v.Asset_B);
});
site.updateLoading(-1);
}
});
if (map.relationOrigin == id) map.paintingRelations = false;
});
}
map.paintingRelations = false;
map.relationOrigin = -1;
map.showParentRelations = function(id) {
site.updateLoading(1);
var parent = api.Assets.getAsset(id, function(parent){
//site.updateLoading(1);
api.Assets.getParentRelations(id, function(relations){
if (parent.hidden != 1 && parent.hidden != true) map.relatedIconsInCurrentArea.push(map.getMarker(parent.id));
if (!relations || relations.length === 0){
site.updateLoading(-1);
} else {
$.each(relations, function(k, v) {
if (v.AssetA.AreaId != parent.AreaId) {
// Child is on a different map -> Add a jump to icon
var icon = L.marker(new L.LatLng(v.AssetA.x, v.AssetA.y), {
icon: map.jumpIcon
}).bindPopup(map.getJumpHtml(v.AssetA.AreaId));
icon.dataitem = v.AssetA;
if (v.AssetA.hidden != 1 && v.AssetA.hidden != true) map.relatedIconsInOtherAreas.push(icon);
map.relationLayer.addLayer(icon);
} else {
if (v.AssetA.hidden != 1 && v.AssetA.hidden != true) map.relatedIconsInCurrentArea.push(map.getMarker(v.Asset_A));
}
var line = L.polyline([new L.LatLng(parent.x, parent.y), new L.LatLng(v.AssetA.x, v.AssetA.y)], {
color: 'green'
});
map.relationLayer.addLayer(line);
// Possibly make a recursive call to display the entire family tree of children
map.showParentRelations(v.Asset_A);
});
site.updateLoading(-1);
}
});
if (map.relationOrigin == id) map.paintingRelations = false;
});
}
map.toggleEmergencyMode = function(){
if (!map.emergencymode) {
$('#emergency-assets').addClass('active');
map.currentcategory = 999;
map.emergencymode = true;
map.loadTiles();
} else {
$('#emergency-assets').removeClass('active');
map.currentcategory = -1;
map.emergencymode = false;
map.loadTiles();
}
}
map.showposition = function(e) {
$('#version').html('<span>' + e.latlng.lat.toString().substring(0, 6) + ", " + e.latlng.lng.toString().substring(0, 6) + '</span>');
}
map.startNewArea = function() {
var area = api.Areas.build();
}
map.createTicket = function(id) {
window.location.hash = '#ticket?relations=' + id;
}
map.getAssetPopupHtml = function (v) {
return "<h4>" + v.name + "</h4>" +
"<ul class='nav'>" +
"<li security-role=\"developers administrators maintenance maintenanceadmin\"><a onclick='map.createTicket(" + v.id + ");'>Create Ticket</a></li>" +
"<li security-role=\"developers administrators assetman assetmanadmin\"><a onclick='map.duplicate(" + v.id + ");'>Duplicate</a></li>" +
"<li security-role=\"developers administrators assetman assetmanadmin\"><a onclick='map.duplicate(" + v.id + ",true);'>Duplicate With Children</a></li>" +
"<li security-role=\"developers administrators assetman assetmanadmin\"><a onclick='map.startchildasset(" + v.id + ");'>Assign Child</a></li>" +
"<li security-role=\"developers administrators assetman assetmanadmin\"><a onclick='map.startparentasset(" + v.id + ");'>Assign Parent</a></li>" +
"<li security-role=\"developers administrators assetmanadmin\"><a onclick='map.beginmove(" + v.id + ");'>Move</a></li>" +
"<li><a onclick='map.startShowRelations(" + v.id + ", site.hideLoading);'>Show Children</a></li>" +
"<li><a onclick='map.startShowParentRelations(" + v.id + ",site.hideLoading);'>Show Parents</a></li>" +
"</ul>" +
"<div class='modal-footer'>" +
"<a class='btn btn-primary' href='#asset-details?id=" + v.id + "'>Details</a>" +
"</div>";
}
map.startnewpano = function() {
bootbox.alert('To begin creating this panoramic please choose a point on the map.');
map.currentasset = api.Assets.build();
map.currentasset.category = 12;
map.currentasset.type = 0;
map.currentasset.AreaId = map.currentarea.id;
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.toggleCancel('Cancel New Panoramic', function(){
map.toggleCancel();
map.root.off('click');
$('body').css({
'cursor': 'pointer'
});
});
map.root.on('click', function(e) {
map.toggleCancel();
map.currentasset.x = e.latlng.lat;
map.currentasset.y = e.latlng.lng;
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
showAssetDetails();
bootbox.alert("Using the upload button, upload the zip file containing the panoramic");
});
}
/*
Given the current view and category fetch all assets from the database
*/
map.loadVisibleAssets = function() {
if (!map.currenttype) map.currenttype = 0;
if (map.root && map.root.getZoom() >= 3) {
if (map.assets) {
//map.assets.clearLayers();
} else {
map.assets = new L.LayerGroup();
}
if (typeof map.currentcategory !== 'undefined') {
var loadAssets = map.emergencymode ? api.Assets.getEmergencyAssets : api.Assets.getAssetsByCategoryAndType;
loadAssets(function(data) {
map.currentassets = data;
$.each(map.currentassets, function(k, v) {
var exists = false;
_.each(map.assets._layers, function(t){
if (t.dataitem && t.dataitem.id === v.id) {
console.log('Asset Already Exists');
exists = true;
}
});
if (!exists) {
var a = L.marker([v.x, v.y], {
icon: (v.emergency ? map.emergencyMarker : new L.Icon.Default()),
title: v.name,
fill: true,
fillColor: 'red',
radius: 10,
color: 'red',
opacity: 1,
fillOpacity: 1
}).bindLabel(v.name + " [" + v.id + "]");
if (v.category === 12) {
a.bindPopup("<h4>Panoramic</h4>" + "<ul class='nav'>" + "<li><a onclick='map.beginmove(" + v.id + ");'>Move</a></li>" + "<li><a href='#pano?id=" + v.id + "'>View Panoramic</a></li>", {
maxWidth: 300,
minWidth: 300,
autoPan: false
})
} else {
a.bindPopup(map.getAssetPopupHtml(v), {
maxWidth: 300,
minWidth: 200,
autoPan: false
})
}
a.dataitem = v;
a.on('click', map.clearRelationLayer);
map.assets.addLayer(a);
if ((!v.status || v.status.value === 'Incomplete') && site.hasRole('developers') || site.hasRole('administrators') || site.hasRole('assetman') || site.hasRole('assetmanadmin') || site.hasRole('maintenance') || site.hasRole('maintenanceadmin') || site.hasRole('watchman') || site.hasRole('roundsadmin')) {
var warning = L.marker([v.x, v.y], {
icon: map.warningIcon
});
map.assets.addLayer(warning);
}
}
});
$('#tbody-' + map.currentcategory).html('');
$.each(map.currentassets, function(k, asset) {
var html = '<tr>' + '<td><a href="#asset-details?id=' + asset.id + '">' + asset.name + '</a></td>' + '<td>' + api.Assets.categories()[map.currentcategory].types[asset.type].name + '</td>' + '</tr>';
$('#tbody-' + map.currentcategory).append(html);
});
}, map.root.getCenter().lat, map.root.getCenter().lng, map.currentcategory, map.currenttype, map.root.getZoom(), map.currentarea.id);
}
map.root.addLayer(map.assets)
};
if (map.root && map.root.getZoom() < 3 && map.assets) {
map.root.removeLayer(map.assets);
};
}
map.renameRoom = function(id) {
var tag = map.getRoomTag(id);
var room = tag.dataitem;
room.name = prompt('Current Room Name: ' + room.name + "\n\n Please enter a new \"Friendly Name\" thats easy to understand: ");
tag.dataitem = api.Rooms.setRoom(room);
tag.closePopup();
tag.unbindPopup();
tag.bindPopup(map.getRoomTagHtml(room), {
maxWidth: 300,
minWidth: 300,
autoPan: false
});
tag.updateLabelContent(room.name && room.name.length > 0 ? room.name : room.uniqueid);
tag.showLabel();
tag.openPopup();
}
map.roomTagsHidden = false;
map.toggleRoomTags = function() {
if (map.roomTagsHidden) {
$.each(map.roomTags._layers, function(k, tag) {
tag.showLabel();
map.roomTagsHidden = false;
});
} else {
$.each(map.roomTags._layers, function(k, tag) {
tag.hideLabel();
map.roomTagsHidden = true;
});
}
}
map.changeRoomNumber = function(id) {
var tag = map.getRoomTag(id);
var room = tag.dataitem;
room.uniqueid = prompt('Current Room Number: ' + room.name + "\n\n Please enter a new Room Number that follows the proper naming convention: ");
tag.dataitem = api.Rooms.setRoom(room);
tag.closePopup();
tag.unbindPopup();
tag.bindPopup(map.getRoomTagHtml(room), {
maxWidth: 300,
minWidth: 300,
autoPan: false
});
tag.bindLabel(room.name && room.name.length > 0 ? room.name : room.uniqueid, {
noHide: true
});
tag.showLabel();
tag.openPopup();
}
map.deleteRoom = function (id) {
if (site.hasRole('administrators') || site.hasRole('developers') || site.hasRole('assetmanadmin')) {
bootbox.confirm('Are you SURE you want to delete this room? Deleting this room will delete all the assets in the room.', function (val) {
if (val) {
if (api.Rooms.delete(id)) {
var tag = map.getRoomTag(id);
map.roomTags.removeLayer(tag);
}
}
});
} else {
bootbox.alert("You are not authorized to delete this room (administrators and developers only).");
}
}
map.getRoomTagHtml = function (v) {
return "<h4>" + v.name + " <small>" + v.uniqueid + "</small></h4>" + "<ul class='nav'>" + "<li security-role=\"developers administrators assetmanadmin\"><a onclick='map.startPlaceTag(" + v.id + ")'>Move</a></li>" + "<li security-role=\"developers administrators assetmanadmin\"><a onclick='map.deleteRoom(" + v.id + ")'>Delete Room</a></li>" + "</ul>" + "<div class='modal-footer'>" + "<a class='btn btn-primary' href='#room-details?id=" + v.id + "'>Details</a>" + "</div>"
}
/*
Given the current view and category fetch all assets from the database
*/
map.loadVisibleRoomTags = function () {
if (map.root.getZoom() >= 3) {
if (map.roomTags) {
//map.roomTags.clearLayers();
} else {
map.roomTags = new L.LayerGroup();
}
api.Rooms.getRoomsByArea(function (data) {
// When I get here
// you have data inside the object called data
$.each(data, function (k, v) {
var exists = false;
_.each(map.roomTags._layers, function (t) {
if (t.dataitem && t.dataitem.id === v.id) {
exists = true;
}
});
if (!exists) {
// We need to limit the room popup to developers/admins/assetman/assetmanadmin/maintenance/maintenanceadmin
var a = L.marker([v.x, v.y], {
title: v.name,
icon: map.roomIcon
}).bindLabel(v.name && v.name.length > 0 ? v.name : v.uniqueid, {
noHide: true
});
// if ( site.hasRole('developers')
// || site.hasRole('administrators')
// || site.hasRole('assetman')
// || site.hasRole('assetmanadmin')
// || site.hasRole('maintenance')
// || site.hasRole('maintenanceadmin'))
{
a.bindPopup(map.getRoomTagHtml(v), {
maxWidth: 300,
minWidth: 300,
autoPan: false
});
}
a.dataitem = v;
map.roomTags.addLayer(a);
}
})
map.root.addLayer(map.roomTags)
$.each(map.roomTags._layers, function (k, v) {
v.showLabel();
});
}, map.currentarea.id);
};
if (map.root.getZoom() < 3 && map.roomTags) {
map.root.removeLayer(map.roomTags);
map.roomTags = null;
};
}
map.where = function () {
alert(latitude + ' ' + longitude);
}
map.geo_callback = function(position) {
enableHighAccuracy: true;
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log(latitude + ", " + longitude);
if (latitude >= 40.73291 && latitude <= 40.73363 &&
longitude >= -74.06163 && longitude <= -74.063) {
// at jcah
bootbox.confirm('Would you like to center your view on your current location?',
function(yesno){
if (yesno){
map.root.panTo([latitude, longitude]);
map.root.setZoom(5);
}
}
);
}
}
site.pageUnloaded = function() {
$(window).off('resize.map');
map.root = null;
}
/*
This begins the creation of an asset that does not have physical representation but is bound to another asset
*/
map.startchildasset = function(parentid) {
bootbox.dialog('Please choose whether this asset exists in the same location as its parent or will it have its own location.', [{
"label": "Choose Existing Asset",
"callback": function() {
site.findAsset(function(results) {
if (results && results.length > 0) {
for (var i = 0; i < results.length; i++) {
var relation = api.Assets.buildRelation();
relation.Asset_A = parentid;
relation.Asset_B = results[i].id;
api.Assets.setRelation(relation);
}
} else if (results && results.id) {
var relation = api.Assets.buildRelation();
relation.Asset_A = parentid;
relation.Asset_B = results.id;
api.Assets.setRelation(relation);
} else if (results) {
bootbox.confirm('Creating a new child from this screen will create a child without physical representation. Is this ok?', function() {
map.tempRelation = api.Assets.buildRelation();
map.tempRelation.Asset_A = parentid;
map.tempRelation.AssetA = api.Assets.getAsset(parentid);
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.tempRelation.AssetA.AreaId;
map.currentasset.RoomId = map.tempRelation.AssetA.RoomId;
map.currentasset.hidden = true;
map.currentasset.category = !map.currentcategory ? 0 : map.currentcategory;
map.currentasset.x = map.tempRelation.AssetA.x;
map.currentasset.y = map.tempRelation.AssetA.y;
showAssetDetails();
});
}
});
}
}, {
"label": "Same Location as Parent",
"callback": function() {
map.tempRelation = api.Assets.buildRelation();
map.tempRelation.Asset_A = parentid;
map.tempRelation.AssetA = api.Assets.getAsset(parentid);
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.tempRelation.AssetA.AreaId;
map.currentasset.RoomId = map.tempRelation.AssetA.RoomId;
map.currentasset.hidden = true;
map.currentasset.category = !map.currentcategory ? 0 : map.currentcategory;
map.currentasset.x = map.tempRelation.AssetA.x;
map.currentasset.y = map.tempRelation.AssetA.y;
showAssetDetails();
}
}, {
"label": "Choose Place on Map",
"callback": function() {
map.tempRelation = api.Assets.buildRelation();
map.tempRelation.Asset_A = parentid;
map.tempRelation.AssetA = api.Assets.getAsset(parentid);
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.tempRelation.AssetA.AreaId;
map.currentasset.RoomId = map.tempRelation.AssetA.RoomId;
map.currentasset.hidden = false;
map.currentasset.category = !map.currentcategory ? 0 : map.currentcategory;
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.root.on('click', function(e) {
map.currentasset.x = e.latlng.lat;
map.currentasset.y = e.latlng.lng;
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
showAssetDetails();
});
}
}]);
}
/*
This begins the creation of an asset that does not have physical representation but is bound to another asset
*/
map.startparentasset = function(childid) {
bootbox.dialog('Please choose whether this asset exists in the same location as its parent or will it have its own location.', [{
"label": "Choose Existing Asset",
"callback": function() {
site.findAsset(function(results) {
if (results && results.length > 0) {
for (var i = 0; i < results.length; i++) {
var relation = api.Assets.buildRelation();
relation.Asset_B = childid;
relation.Asset_A = results[i].id;
api.Assets.setRelation(relation);
}
} else if (results && results.id) {
var relation = api.Assets.buildRelation();
relation.Asset_B = childid;
relation.Asset_A = results.id;
api.Assets.setRelation(relation);
} else if (results) {
bootbox.confirm('Creating a new parent from this screen will create a parent without physical representation. Is this ok?', function() {
map.tempRelation = api.Assets.buildRelation();
map.tempRelation.Asset_B = childid;
map.tempRelation.AssetB = api.Assets.getAsset(childid);
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.tempRelation.AssetB.AreaId;
map.currentasset.RoomId = map.tempRelation.AssetB.RoomId;
map.currentasset.hidden = true;
map.currentasset.category = !map.currentcategory ? 0 : map.currentcategory;
map.currentasset.x = map.tempRelation.AssetB.x;
map.currentasset.y = map.tempRelation.AssetB.y;
showAssetDetails();
});
}
});
}
}, {
"label": "Choose Place on Map",
"callback": function() {
map.tempRelation = api.Assets.buildRelation();
map.tempRelation.Asset_A = parentid;
map.tempRelation.AssetA = api.Assets.getAsset(parentid);
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.tempRelation.AssetA.AreaId;
map.currentasset.RoomId = map.tempRelation.AssetA.RoomId;
map.currentasset.hidden = false;
map.currentasset.category = !map.currentcategory ? 0 : map.currentcategory;
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.root.on('click', function(e) {
map.currentasset.x = e.latlng.lat;
map.currentasset.y = e.latlng.lng;
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
showAssetDetails();
});
}
}]);
}
map.startnewasset = function() {
bootbox.alert('To begin creating this asset please choose a point on the map.', function() {
map.currentasset = api.Assets.build();
map.currentasset.AreaId = map.currentarea.id;
map.currentasset.category = !map.currentcategory || map.currentcategory === -1 ? 0 : map.currentcategory;
moving = true;
$('body').css({
'cursor': 'pointer'
});
map.toggleCancel('Cancel New Asset', function(){
map.toggleCancel();
map.root.off('click');
$('body').css({
'cursor': 'default'
});
});
map.root.on('click', function(e) {
map.toggleCancel();
map.currentasset.x = e.latlng.lat;
map.currentasset.y = e.latlng.lng;
moving = false;
map.root.off('click');
$('body').css({
'cursor': 'default'
});
showAssetDetails();
});
});
}
map.emergencymode = false;
/*
Handles the loading/reloading of the entire map based on the given areaid
*/
map.loadTiles = function (areaid, keepRelations, cb) {
if (keepRelations) {
// Do Nothing
} else {
map.clearRelationLayer();
}
if (map.assets) {
map.assets.clearLayers();
map.root.removeLayer(map.assets);
map.currentassets = [];
}
if (map.roomTags) {
map.roomTags.clearLayers();
map.root.removeLayer(map.roomTags);
}
if (areaid) map.currentarea = api.Areas.getArea(areaid);
else areaid = map.currentarea.id;
if (map.currentcategory || map.currentcategory === 0) {
var alternate = api.Areas.getMap(map.currentarea.id, map.currentcategory);
if (alternate && !map.emergencymode) areaid = map.currentarea.id + '/' + map.currentcategory;
}
map.loadMapRoot();
if (map.tiles) {
map.tiles.setUrl('areamaps/' + areaid + '/tile_{z}_{x}-{y}.png');
outLayer.setUrl('areamaps/' + areaid + '/tile_{z}_{x}-{y}.png');
} else {
map.tiles = L.tileLayer('areamaps/' + areaid + '/tile_{z}_{x}-{y}.png', {
maxZoom: 5,
attribution: '',
noWrap: true,
reuseTiles: true,
continuousWorld: true,
scrollWheelZoom: true,
dragging: true
}).addTo(map.root);
outLayer = new L.TileLayer('areamaps/' + areaid + '/tile_{z}_{x}-{y}.png', {
maxZoom: 1,
noWrap: true,
continuousWorld: true,
toggleDisplay: true
});
miniMap = new L.Control.MiniMap(outLayer).addTo(map.root);
}
$('.leaflet-container').css({
"background-color": "white"
});
map.loadVisibleRoomTags();
map.loadVisibleAssets();
if(cb) cb();
}
map.showAssetsByCategory = function(cat){
api.Assets.queryAssets({
hidden: 0,
category: cat,
AreaId: map.currentarea.id
}, function(data){
$('#modals').append(Mustache.to_html($('#template-assetlist').html(),{
header: api.Assets.categories()[cat].name,
assets: data
}));
$('#modalassets-cancel').click(function(){
$('#modalassets').remove();
$('.modal-backdrop').remove();
});
});
}
map.showAssetsByCategoryAndType = function(context){
api.Assets.queryAssets({
hidden: 0,
category: $($(context)[0].parentNode.parentNode.parentNode).data('category').toString(),
type: $(context).data('type').toString(),
AreaId: map.currentarea.id
}, function(data){
alert('');
$('#modals').append(Mustache.to_html($('#template-assetlist').html(),{
header: api.Assets.categories()[cat].name,
assets: data
}));
$('#modalassets-cancel').click(function(){
$('#modalassets').remove();
$('.modal-backdrop').remove();
});
});
}
map.loadMapRoot = function(){
if (!map.root) {
map.root = L.map('mapdiv').setView([0, 0], 2);
}
}
/*
Given the current Query String load the appropriate map information:
Query String Format:
a = Area ID
z = Zoom Level
*/
map.loadFromQString = function() {
var areaid = site.qString['area'],
z = site.qString['z'],
c = site.qString['c'],
x = site.qString['x'],
y = site.qString['y'],
t = site.qString['t'];
if (!areaid) {
var areas = map.areaListCache;
if (!areas || areas.length === 0) alert('No areas created. See Administrator for initial setup!');
else areaid = areas[0].id;
}
//map.loadTiles(areaid);
map.currentarea = api.Areas.getArea(areaid);
map.currenttype = parseInt(t);
map.loadMapRoot();
if (!c || c === 'null' || c === '' || c === 'NaN') c = -1;
map.currentcategory = c;
map.loadTiles(null, true, function(){
//if (c) map.selectCategory(c);
if (x && y) map.root.panTo([x, y]);
if (z) map.root.setZoom(z);
});
//setTimeout(function(){
//}, 500);
}
var loadingAreaList = false;
map.areaListCache = [];
map.loadAreaList = function() {
loadingAreaList = true;
$.ajax({
url: '/areas',
type: 'GET',
async: false,
success: function(areas) {
map.areaListCache = areas;
$('.arealist-item').remove();
$.each(areas, function(k, v) {
$('#arealist li:last').after('<li class="arealist-item" data-item="' + v.name + '"><a onclick="map.loadTiles(' + v.id + ');">' + v.name + '</a></li>');
});
}
});
loadingAreaList = false;
$('#arealist').change(function() {
if (!loadingAreaList) {
map.loadTiles($('#arealist').val());
}
});
$('.arealist-item').sortElements(function(a, b){
return $(a).attr('data-item') > $(b).attr('data-item') ? 1 : -1;
});
}
map.selectType = function(context) {
$.sidr('close', 'map-controls');
map.currentcategory = $($(context)[0].parentNode.parentNode).data('category');
map.currenttype = $(context).data('type');
map.loadTiles(null, false, function(){
map.loadVisibleAssets();
map.loadTiles();
});
}
map.getActiveCategory = function() {
$('.accordion-body').each(function(k, v) {
if ($(v).hasClass('in')) {
return $(v);
}
});
return null;
}
map.skipAssetLoading = false;
map.beforeActivate = function() {
if (!map.skipAssetLoading) {
if (map.emergencymode) map.toggleEmergencyMode();
var ui = {
newHeader: $(this)
};
$('.accordion-body').each(function(k, v) {
if ($(v).attr('db-category') != $(ui.newHeader).attr('db-category')) {
$(v).collapse('hide');
}
});
if (ui.newHeader) {
map.currentcategory = $(ui.newHeader).attr('db-category');
map.loadVisibleAssets();
map.loadTiles();
map.updateQueryString();
} else {
map.loadTiles();
}
}
}
map.updateCurrentUsersLocation = function(){
site.currentuser.map = {
area: map.currentarea.id,
x: map.currentLatitude,
y: map.currentLongitude,
z: map.currentZoom,
category: map.currentcategory
};
api.Users.setUser(site.currentuser, function(){}, false);
}
map.updateQueryString = function () {
map.currentLatitude = map.root.getCenter().lat;
map.currentLongitude = map.root.getCenter().lng;
map.currentZoom = map.root.getZoom();
if (window.location.hash === '') {
skipLoad = true;
window.location.hash = '#map';
skipLoad = false;
}
map.updateCurrentUsersLocation();
updateQString('area=' + map.currentarea.id + '&x=' + map.currentLatitude + '&y=' + map.currentLongitude + '&z=' + map.currentZoom + (typeof map.currentcategory != 'undefined'? '&c=' + map.currentcategory : '') + (map.currenttype ? '&t=' + map.currenttype : ''));
site.returnUrl = '#map?' + 'area=' + map.currentarea.id + '&x=' + map.currentLatitude + '&y=' + map.currentLongitude + '&z=' + map.currentZoom + (map.currentcategory ? '&c=' + map.currentcategory : '') + (map.currenttype ? '&t=' + map.currenttype : '');
}
map.maximizeMap = function () {
$('#mapdiv').height(window.innerHeight - 105);
$('#mapdiv').width(window.innerWidth);
}
/*
BEGIN FIRST TIME RUN LOGIC
*/
var sort_by = function(field, reverse, primer){
var key = function (x) {return primer ? primer(x[field]) : x[field]};
return function (a,b) {
var A = key(a), B = key(b);
return ((A < B) ? -1 : (A > B) ? +1 : 0) * [-1,1][+!!reverse];
}
}
$('#mainAccordion').empty();
$.each(api.Assets.categories().sort(sort_by('name', true, function(a){return a.toUpperCase()})), function(k, category) {
$('#mainAccordion').append(Mustache.render(map.accordionTemplate, category));
});
//$(".accordion-body").collapse();
//$('.accordion-body').on('shown', map.beforeActivate);
//$('#asset-accordion').append('<div class="accordion-heading">' + '<a class="btn accordion-toggle" href="#unbound-assets"><span class="opener">Unbound Assets</span></a>' + '</div>');
//$('#asset-accordion').append('<div class="accordion-heading">' + '<a onclick="map.toggleEmergencyMode();" id="emergency-assets" class="btn accordion-toggle" ><span class="opener">Emergency Mode</span></a>' + '</div>');
//$("#categories-list-toggle").click(function() {
// $(this).toggleClass("open"), $("#categories").toggleClass("open"), $('.leaflet-control-container .leaflet-left').toggleClass('open');
// map.updateQueryString();
//});
$('.navbar-fixed-top li').removeClass('active');
$("li.map-page").addClass('active');
$('textarea').autosize();
if ( $(document).width() < '801') {
$('#sidenav li a').click(function () {
$('.wizard .tabs-left').removeClass('in').css('height', '');
$('.wizard .btn-navbar.visible-phone').addClass('collapsed');
});
};
$('body').attr('class', 'map-page');
$(window).on('resize.map', function() {
map.maximizeMap();
$('mapcontrols').css({
'height': window.innerHeight - 137
});
});
$('mapcontrols').css({
'height': window.innerHeight - 137
});
map.maximizeMap();
map.loadAreaList();
// When loading the map without any specific query string, user the map object in the current user
api.Users.current(function(user){
if (!site.qString.area && user && user.map && user.map.area) {
console.log('loading from previous map');
var q = "area=" + user.map.area;
q += "x=" + user.map.x;
q += "y=" + user.map.y;
q += "z=" + user.map.z;
q += "c=" + user.map.category;
site.qString.area = user.map.area;
site.qString.x = user.map.x;
site.qString.y = user.map.y;
site.qString.z = user.map.z;
site.qString.c = user.map.category;
updateQString(q);
}
map.loadFromQString();
map.root.on('moveend', map.loadVisibleAssets);
map.root.on('moveend', map.loadVisibleRoomTags);
map.root.on('moveend', map.updateQueryString);
map.root.on('mousemove', map.showposition);
map.root.on("popupopen", function (evt) {
map.currentPopup = evt.popup
});
if (navigator.geolocation)
navigator.geolocation.getCurrentPosition(map.geo_callback);
page.loading = false;
});
//map.loadFromQString();
//map.root.on('zoomend', map.loadVisibleAssets);
$('.side-controls-toggle').sidr({
name : 'map-controls'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment