Skip to content

Commit

Permalink
Merge pull request #4992 from archesproject/4670_geojson_card_component
Browse files Browse the repository at this point in the history
refactors map card component
  • Loading branch information
robgaston authored Jul 10, 2019
2 parents 33c56b8 + 646f87e commit bbb332d
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 122 deletions.
15 changes: 12 additions & 3 deletions arches/app/media/css/arches.css
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,10 @@ ul.tabbed-report-tab-list {
margin-top: -30px;
}

.mouse-pointer canvas {
cursor: pointer;
}

.map-card-wrapper {
flex: 1;
height: 100%;
Expand Down Expand Up @@ -1390,14 +1394,19 @@ ul.tabbed-report-tab-list {
.map-card-feature-list .table {
margin-bottom: 0;
}

.map-card-feature-tool {
font-size: 0.9em;
width: 65px;
}
.map-card-feature-tool a {
.map-card-zoom-tool, .map-card-feature-tool {
font-size: 0.9em;
}
.map-card-zoom-tool a, .map-card-feature-tool a {
color: #2f527a;
}
.map-card-zoom-tool {
float: right;
padding: 10px;
}

#map-settings {
position: relative;
Expand Down
158 changes: 83 additions & 75 deletions arches/app/media/js/views/components/cards/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,103 +3,113 @@ define([
'knockout',
'knockout-mapping',
'uuid',
'mapbox-gl',
'mapbox-gl-draw',
'geojson-extent',
'viewmodels/card-component',
'views/components/map',
'bindings/chosen'
], function(_, ko, koMapping, uuid, MapboxDraw, CardComponentViewModel, MapComponentViewModel) {
], function(_, ko, koMapping, uuid, mapboxgl, MapboxDraw, geojsonExtent, CardComponentViewModel, MapComponentViewModel) {
return ko.components.register('map-card', {
viewModel: function(params) {
var self = this;
var widgets = [];
var padding = 40;
var drawFeatures;
var newNodeId;
this.featureLookup = {};
this.selectedFeatureIds = ko.observableArray();
this.draw = null;

CardComponentViewModel.apply(this, [params]);
MapComponentViewModel.apply(this, [params]);

this.activeTab('editor');
this.featureLookup = {};
var getDrawFeatures = function() {
var drawFeatures = [];
self.card.widgets().forEach(function(widget) {
var nodeId = widget.node_id();
if (self.form && self.form.nodeLookup[nodeId].datatype() === 'geojson-feature-collection' && self.tile) {
var featureCollection = koMapping.toJS(self.tile.data[nodeId]);
if (featureCollection) {
featureCollection.features.forEach(function(feature) {
if (!feature.id) {
feature.id = uuid.generate();
}
feature.properties.nodeId = nodeId;
});
drawFeatures = drawFeatures.concat(featureCollection.features);
}
}
});
return drawFeatures;
};
var drawFeatures = getDrawFeatures();
var newNodeId;
this.card.widgets().forEach(function(widget) {
var nodeId = widget.node_id();
if (self.form && self.form.nodeLookup[nodeId].datatype() === 'geojson-feature-collection') {
self.featureLookup[nodeId] = {
if (self.form && self.tile) self.card.widgets().forEach(function(widget) {
var id = widget.node_id();
var type = self.form.nodeLookup[id].datatype();
if (type === 'geojson-feature-collection') {
widgets.push(widget);
self.featureLookup[id] = {
features: ko.computed(function() {
var features = [];
if (self.tile) {
var featureCollection = koMapping.toJS(self.tile.data[nodeId]);
if (featureCollection) {
features = featureCollection.features;
}
}
return features;
var value = koMapping.toJS(self.tile.data[id]);
if (value) return value.features;
else return [];
}),
selectedTool: ko.observable()
};
self.featureLookup[nodeId].selectedTool.subscribe(function(selectedTool) {
self.featureLookup[id].selectedTool.subscribe(function(tool) {
if (self.draw) {
if (selectedTool === '') {
if (tool === '') {
self.draw.changeMode('simple_select');
} else if (selectedTool) {
} else if (tool) {
_.each(self.featureLookup, function(value, key) {
if (key !== nodeId) {
if (key !== id) {
value.selectedTool(null);
}
});
newNodeId = nodeId;
self.draw.changeMode(selectedTool);
newNodeId = id;
self.draw.changeMode(tool);
}
}
});
}
});

var updateFeatures = function() {
var updateTiles = function() {
var featureCollection = self.draw.getAll();
_.each(self.featureLookup, function(value) {
value.selectedTool(null);
});
self.card.widgets().forEach(function(widget) {
var nodeId = widget.node_id();
if (self.form && self.form.nodeLookup[nodeId].datatype() === 'geojson-feature-collection') {
var nodeFeatures = [];
featureCollection.features.forEach(function(feature){
if (feature.properties.nodeId === nodeId) nodeFeatures.push(feature);
widgets.forEach(function(widget) {
var id = widget.node_id();
var features = [];
featureCollection.features.forEach(function(feature){
if (feature.properties.nodeId === id) features.push(feature);
});
if (ko.isObservable(self.tile.data[id])) {
self.tile.data[id]({
type: 'FeatureCollection',
features: features
});
if (ko.isObservable(self.tile.data[nodeId])) {
self.tile.data[nodeId]({
type: 'FeatureCollection',
features: nodeFeatures
});
} else {
self.tile.data[nodeId].features(nodeFeatures);
}
} else {
self.tile.data[id].features(features);
}
});
};

var getDrawFeatures = function() {
var drawFeatures = [];
widgets.forEach(function(widget) {
var id = widget.node_id();
var featureCollection = koMapping.toJS(self.tile.data[id]);
if (featureCollection) {
featureCollection.features.forEach(function(feature) {
if (!feature.id) {
feature.id = uuid.generate();
}
feature.properties.nodeId = id;
});
drawFeatures = drawFeatures.concat(featureCollection.features);
}
});
return drawFeatures;
};
drawFeatures = getDrawFeatures();

if (drawFeatures.length > 0) {
params.bounds = geojsonExtent({
type: 'FeatureCollection',
features: drawFeatures
});
params.fitBoundsOptions = { padding: padding };
}
params.activeTab = 'editor';

MapComponentViewModel.apply(this, [params]);

this.deleteFeature = function(feature) {
if (self.draw) {
self.draw.delete(feature.id);
updateFeatures();
updateTiles();
}
};

Expand All @@ -122,8 +132,16 @@ define([
map.setStyle(style);
};

this.selectedFeatureIds = ko.observableArray();
this.draw = null;
this.fitFeatures = function(features) {
var map = self.map();
var bounds = geojsonExtent({
type: 'FeatureCollection',
features: features
});
var camera = map.cameraForBounds(bounds, { padding: padding });
map.jumpTo(camera);
};

this.map.subscribe(function(map) {
self.draw = new MapboxDraw({
displayControlsDefault: false
Expand All @@ -137,11 +155,11 @@ define([
e.features.forEach(function(feature) {
self.draw.setFeatureProperty(feature.id, 'nodeId', newNodeId);
});
updateFeatures();
updateTiles();
});
map.on('draw.update', updateFeatures);
map.on('draw.delete', updateFeatures);
map.on('draw.modechange', updateFeatures);
map.on('draw.update', updateTiles);
map.on('draw.delete', updateTiles);
map.on('draw.modechange', updateTiles);
map.on('draw.selectionchange', function(e) {
self.selectedFeatureIds(e.features.map(function(feature) {
return feature.id;
Expand All @@ -157,16 +175,6 @@ define([
if (value.selectedTool()) value.selectedTool('');
});
});

setTimeout(function() {
map.resize();
if (drawFeatures.length > 0) {
self.zoomToGeoJSON({
type: 'FeatureCollection',
features: drawFeatures
});
}
}, 1);
});
},
template: {
Expand Down
75 changes: 33 additions & 42 deletions arches/app/media/js/views/components/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ define([
'knockout',
'mapbox-gl',
'mapbox-gl-geocoder',
'geojson-extent',
'text!templates/views/components/map-popup.htm',
'bindings/mapbox-gl',
'bindings/sortable'
], function($, _, arches, ko, mapboxgl, MapboxGeocoder, geojsonExtent, popupTemplate) {
], function($, _, arches, ko, mapboxgl, MapboxGeocoder, popupTemplate) {
var viewModel = function(params) {
var self = this;
var geojsonSourceFactory = function() {
Expand Down Expand Up @@ -39,21 +38,14 @@ define([
this.basemaps = [];
this.overlays = ko.observableArray();
this.activeBasemap = ko.observable();
this.activeTab = ko.observable();
this.activeTab = ko.observable(params.activeTab);
this.hideSidePanel = function() {
self.activeTab(undefined);
};
this.activeTab.subscribe(function() {
var map = self.map();
if (map) setTimeout(function() { map.resize(); }, 1);
});
this.zoomToGeoJSON = function(data, fly) {
var method = fly ? 'flyTo' : 'jumpTo';
var map = self.map();
var bounds = new mapboxgl.LngLatBounds(geojsonExtent(data));
var options = map.cameraForBounds(bounds, {padding: 40});
map[method](options);
};

mapLayers.forEach(function(layer) {
if (!layer.isoverlay) {
Expand Down Expand Up @@ -157,7 +149,8 @@ define([
center: [x, y],
zoom: zoom
},
bounds: bounds
bounds: bounds,
fitBoundsOptions: params.fitBoundsOptions
};

this.toggleTab = function(tabName) {
Expand All @@ -180,35 +173,27 @@ define([
};

var resourceLookup = {};
var lookupResourceData = function(feature) {
var resourceData = feature.properties;
var resourceId = resourceData.resourceinstanceid;
if (resourceLookup[resourceId]) {
return resourceLookup[resourceId];
}
resourceData = _.defaults(resourceData, {
'loading': true,
'displaydescription': '',
'map_popup': '',
'displayname': '',
'graphid': '',
'graph_name': '',
'geometries': []
});
resourceData = ko.mapping.fromJS(resourceData);
resourceData.reportURL = arches.urls.resource_report;
resourceData.editURL = arches.urls.resource_editor;

resourceLookup[resourceId] = resourceData;
$.get(arches.urls.resource_descriptors + resourceId, function(data) {
data.loading = false;
ko.mapping.fromJS(data, resourceLookup[resourceId]);
});
return resourceLookup[resourceId];
};

this.getPopupData = function(feature) {
return lookupResourceData(feature);
var data = feature.properties;
var id = data.resourceinstanceid;
if (id) {
if (resourceLookup[id]) return resourceLookup[id];
data = _.defaults(data, {
'loading': true,
'displayname': '',
'graph_name': ''
});
data = ko.mapping.fromJS(data);
data.reportURL = arches.urls.resource_report;
data.editURL = arches.urls.resource_editor;

resourceLookup[id] = data;
$.get(arches.urls.resource_descriptors + id, function(data) {
data.loading = false;
ko.mapping.fromJS(data, resourceLookup[id]);
});
return resourceLookup[id];
}
};

this.setupMap = function(map) {
Expand All @@ -221,7 +206,7 @@ define([
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
placeholder: arches.geocoderPlaceHolder,
bbox: bounds
bbox: arches.hexBinBounds
}), 'top-right');

layers.subscribe(self.updateLayers);
Expand All @@ -239,18 +224,24 @@ define([

map.on('click', function(e) {
if (hoverFeature) {
var p = new mapboxgl.Popup()
var selectedFeature = hoverFeature;
var popup = new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(self.popupTemplate)
.addTo(map);
ko.applyBindingsToDescendants(
self.getPopupData(hoverFeature),
p._content
popup._content
);
map.setFeatureState(selectedFeature, { selected: true });
popup.on('close', function() {
map.setFeatureState(selectedFeature, { selected: false });
});
}
});

self.map(map);
setTimeout(function() { map.resize(); }, 1);
});
};
};
Expand Down
Loading

0 comments on commit bbb332d

Please sign in to comment.