Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhances and refactors new map component #4940

Merged
merged 9 commits into from
Jun 20, 2019
Prev Previous commit
Next Next commit
refactors map component, re: #4670
  • Loading branch information
robgaston committed Jun 19, 2019
commit 9733c8d718260a9758bf4aa74eb978a16f8b1610
269 changes: 138 additions & 131 deletions arches/app/media/js/views/components/map.js
Original file line number Diff line number Diff line change
@@ -5,156 +5,163 @@ define([
'knockout',
'bindings/sortable'
], function($, _, arches, ko) {
return ko.components.register('arches-map', {
viewModel: function(params) {
var self = this;
var geojsonSourceFactory = function() {
return {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": []
}
};
var viewModel = function(params) {
var self = this;
var geojsonSourceFactory = function() {
return {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": []
}
};
};

this.basemaps = [];
this.overlays = ko.observableArray();
this.activeBasemap = ko.observable();
this.activeTab = ko.observable();
this.hideSidePanel = function() {
self.activeTab(undefined);
};
var x = params.x || arches.mapDefaultX;
var y = params.y || arches.mapDefaultY;
var zoom = params.zoom || arches.mapDefaultZoom;
var bounds = params.bounds || arches.hexBinBounds;

arches.mapLayers.forEach(function(layer) {
if (!layer.isoverlay) {
self.basemaps.push(layer);
if (layer.addtomap) self.activeBasemap(layer);
}
else {
layer.opacity = ko.observable(layer.addtomap ? 100 : 0);
layer.onMap = ko.pureComputed({
read: function() { return layer.opacity() > 0; },
write: function(value) {
layer.opacity(value ? 100 : 0);
}
});
self.overlays.push(layer);
}
});
this.basemaps = [];
this.overlays = ko.observableArray();
this.activeBasemap = ko.observable();
this.activeTab = ko.observable();
this.hideSidePanel = function() {
self.activeTab(undefined);
};

_.each(arches.mapSources, function(sourceConfig) {
if (sourceConfig.tiles) {
sourceConfig.tiles.forEach(function(url, i) {
if (url.startsWith('/')) {
sourceConfig.tiles[i] = window.location.origin + url;
}
});
}
});
arches.mapLayers.forEach(function(layer) {
if (!layer.isoverlay) {
self.basemaps.push(layer);
if (layer.addtomap) self.activeBasemap(layer);
}
else {
layer.opacity = ko.observable(layer.addtomap ? 100 : 0);
layer.onMap = ko.pureComputed({
read: function() { return layer.opacity() > 0; },
write: function(value) {
layer.opacity(value ? 100 : 0);
}
});
self.overlays.push(layer);
}
});

var multiplyStopValues = function(stops, multiplier) {
_.each(stops, function(stop) {
if (Array.isArray(stop[1])) {
multiplyStopValues(stop[1], multiplier);
} else {
stop[1] = stop[1] * multiplier;
_.each(arches.mapSources, function(sourceConfig) {
if (sourceConfig.tiles) {
sourceConfig.tiles.forEach(function(url, i) {
if (url.startsWith('/')) {
sourceConfig.tiles[i] = window.location.origin + url;
}
});
};
}
});

var updateOpacity = function(layer, val) {
var opacityVal = Number(val) / 100.0;
layer = JSON.parse(JSON.stringify(layer));
if (layer.paint === undefined) {
layer.paint = {};
var multiplyStopValues = function(stops, multiplier) {
_.each(stops, function(stop) {
if (Array.isArray(stop[1])) {
multiplyStopValues(stop[1], multiplier);
} else {
stop[1] = stop[1] * multiplier;
}
_.each([
'background',
'fill',
'line',
'text',
'icon',
'raster',
'circle',
'fill-extrusion',
'heatmap'
], function(opacityType) {
var startVal = layer.paint ? layer.paint[opacityType + '-opacity'] : null;
});
};

if (startVal) {
if (parseFloat(startVal)) {
layer.paint[opacityType + '-opacity'].base = startVal * opacityVal;
} else {
layer.paint[opacityType + '-opacity'] = JSON.parse(JSON.stringify(startVal));
if (startVal.base) {
layer.paint[opacityType + '-opacity'].base = startVal.base * opacityVal;
}
if (startVal.stops) {
multiplyStopValues(layer.paint[opacityType + '-opacity'].stops, opacityVal);
}
var updateOpacity = function(layer, val) {
var opacityVal = Number(val) / 100.0;
layer = JSON.parse(JSON.stringify(layer));
if (layer.paint === undefined) {
layer.paint = {};
}
_.each([
'background',
'fill',
'line',
'text',
'icon',
'raster',
'circle',
'fill-extrusion',
'heatmap'
], function(opacityType) {
var startVal = layer.paint ? layer.paint[opacityType + '-opacity'] : null;

if (startVal) {
if (parseFloat(startVal)) {
layer.paint[opacityType + '-opacity'].base = startVal * opacityVal;
} else {
layer.paint[opacityType + '-opacity'] = JSON.parse(JSON.stringify(startVal));
if (startVal.base) {
layer.paint[opacityType + '-opacity'].base = startVal.base * opacityVal;
}
if (startVal.stops) {
multiplyStopValues(layer.paint[opacityType + '-opacity'].stops, opacityVal);
}
} else if (layer.type === opacityType ||
(layer.type === 'symbol' && (opacityType === 'text' || opacityType === 'icon'))) {
layer.paint[opacityType + '-opacity'] = opacityVal;
}
}, self);
return layer;
};
} else if (layer.type === opacityType ||
(layer.type === 'symbol' && (opacityType === 'text' || opacityType === 'icon'))) {
layer.paint[opacityType + '-opacity'] = opacityVal;
}
}, self);
return layer;
};

var layers = ko.pureComputed(function() {
var layers = self.activeBasemap().layer_definitions.slice(0);
self.overlays().forEach(function(layer) {
if (layer.onMap()) {
var opacity = layer.opacity();
layer.layer_definitions.forEach(function(layer) {
layers.push(updateOpacity(layer, opacity));
});
}
});
return layers;
}, this);
var layers = ko.pureComputed(function() {
var layers = self.activeBasemap().layer_definitions.slice(0);
self.overlays().forEach(function(layer) {
if (layer.onMap()) {
var opacity = layer.opacity();
layer.layer_definitions.forEach(function(layer) {
layers.push(updateOpacity(layer, opacity));
});
}
});
return layers;
}, this);

this.mapOptions = {
style: {
version: 8,
sources: Object.assign({
"resource": geojsonSourceFactory(),
"search-results-hex": geojsonSourceFactory(),
"search-results-hashes": geojsonSourceFactory(),
"search-results-points": geojsonSourceFactory()
}, arches.mapSources),
sprite: arches.mapboxSprites,
glyphs: arches.mapboxGlyphs,
layers: layers(),
center: [arches.mapDefaultX, arches.mapDefaultY],
zoom: arches.mapDefaultZoom
},
bounds: arches.hexBinBounds
};
this.mapOptions = {
style: {
version: 8,
sources: Object.assign({
"resource": geojsonSourceFactory(),
"search-results-hex": geojsonSourceFactory(),
"search-results-hashes": geojsonSourceFactory(),
"search-results-points": geojsonSourceFactory()
}, arches.mapSources),
sprite: arches.mapboxSprites,
glyphs: arches.mapboxGlyphs,
layers: layers(),
center: [x, y],
zoom: zoom
},
bounds: bounds
};

this.toggleTab = function(tabName) {
if (self.activeTab() === tabName) {
self.activeTab(null);
} else {
self.activeTab(tabName);
}
};
this.toggleTab = function(tabName) {
if (self.activeTab() === tabName) {
self.activeTab(null);
} else {
self.activeTab(tabName);
}
};

this.setupMap = function(map) {
if (ko.isObservable(params.map)) {
params.map(map);
}
this.setupMap = function(map) {
if (ko.isObservable(params.map)) {
params.map(map);
}

layers.subscribe(function(layers) {
var style = map.getStyle();
style.layers = layers;
map.setStyle(style);
});
};
},
layers.subscribe(function(layers) {
var style = map.getStyle();
style.layers = layers;
map.setStyle(style);
});
};
};
ko.components.register('arches-map', {
viewModel: viewModel,
template: {
require: 'text!templates/views/components/map.htm'
}
});
return viewModel;
});