trash/to_port/geo-map-state.js.txt
(function() {
var ns = Jassa.geo;
// ns.createMapDiff = function(a, b) {
//
// var aIds = _(a).keys();
// var bIds = _(b).keys();
//
// var addedIds = _(aIds).difference(bIds);
// var removedIds = _(bIds).difference(aIds);
//
// var added = _(a).pick(addedIds);
// var remoed = _(b).pick(removedIds);
//
// var result = {
// added: added,
// removed: removed
// };
//
// return result;
// };
ns.ViewStateUtils = {
createStateHash: function(sparqlService, geoMap, concept) {
var serviceHash = sparqlService.getStateHash();
var geoHash = JSON.stringify(geoMap); //geoMap.getElementFactory().createElement().toString();
var conceptHash = '' + concept;
var result = serviceHash + geoHash + conceptHash;
return result;
},
// TODO This function is generig; move to a better location
diffObjects: function(newObjs, oldObjs, idFn) {
//function(node) {return node.getNodeId(); }
var newIdToObj = _(newObjs).indexBy(idFn);
var oldIdToObj = _(oldObjs).indexBy(idFn);
var newIds = _(newIdToObj).keys();
var oldIds = _(oldIdToObj).keys();
var retainedIds = _(newIds).intersection(oldIds);
var result = {
retained: _(oldIdToObj).chain().pick(retainedIds).values().value(),
added: _(newIdToObj).chain().omit(oldIds).values().value(),
removed: _(oldIdToObj).chain().omit(newIds).values().value()
};
return result;
},
diffViewStates: function(newViewState, oldViewState) {
//oldViewState = oldViewState || new ns.ViewState();
var newStateHash = newViewState.getStateHash();
var oldStateHash = oldViewState ? oldViewState.getStateHash() : '';
var newNodes = newViewState.getNodes();
var oldNodes = oldViewState ? oldViewState.getNodes() : [];
var result;
// If the hashes do not match, replace the whole old state
if(newStateHash != oldStateHash) {
result = {
retained: [],
added: newNodes,
removed: oldNodes
}
}
else {
var idFn = function(node) {
var result = node.getId();
//console.log('NodeId', result);
return result;
};
result = this.diffObjects(newNodes, oldNodes, idFn);
}
return result;
}
};
/**
* TODO/Note This data should be (also) part of the model I suppose
*/
ns.ViewState = Class.create({
initialize: function(sparqlService, geoMap, concept, bounds, nodes) {
this.sparqlService = sparqlService;
//this.concept = concept;
this.geoMap = geoMap;
this.concept = concept;
this.bounds = bounds; //null; //new qt.Bounds(-9999, -9998, -9999, -9998);
this.nodes = nodes;
},
getStateHash: function() {
return ns.ViewStateUtils.createStateHash(this.sparqlService, this.geoMap, this.concept);
},
// TODO Maybe the view state should remain agnostic of service and concept, and
// instead only reveal the nodes that are part of it
getSparqlService: function() {
return this.sparqlService;
},
getGeoMap: function() {
return this.geoMap;
},
// getConcept: function() {
// return this.concept;
// },
/**
* Returns the quad tree nodes intersecting with the viewport
*/
getNodes: function() {
return this.nodes;
},
getBounds: function() {
return this.bounds;
}
//getVisibleG
});
/**
* TODO Maybe replace sparqlService with sparqlServiceFactory?
* But then the object would have to deal with services with different state.
* Or we have a QuadTreeProvider/Factory, that creates QuadTreeObjects as needed,
* depending on the combined state of the service and concept.
* - Or we have a factory, that creates a MapCtrl as needed for each given service.
* I guess the last approach is good enough.
*
*
* Hm, rather I would prefer if some 'template' object was returned,
* that could be instantiated with a service.
*
* mapCtrl.foo(geoMapFactory, conceptFactory).createService(sparqlService);
* or service.execute(mapping?)
*
*/
ns.ViewStateFetcher = Class.create({
//initialize: function(sparqlService, geoMapFactory, conceptFactory) {
initialize: function() {
// this.sparqlService = sparqlService;
// this.geoMapFactory = geoMapFactory;
// this.conceptFactory = conceptFactory;
//this.conceptToService = {};
this.hashToCache = {};
},
//fetchViewState: function(bounds) {
fetchViewState: function(sparqlService, geoMapFactory, concept, bounds, quadTreeConfig) {
// var sparqlService = this.sparqlService;
// var geoMapFactory = this.geoMapFactory;
// var conceptFactory = this.conceptFactory;
quadTreeConfig = quadTreeConfig || {};
_(quadTreeConfig).defaults(ns.ViewStateFetcher.defaultQuadTreeConfig);
//quadTreeConfig =
//var concept = conceptFactory.createConcept();
// TODO Make this configurable
var geoMap = geoMapFactory.createMapForGlobal();
// TODO This should be a concept, I assume
//var geoConcept = geoMap.createConcept();
var hash = ns.ViewStateUtils.createStateHash(sparqlService, geoMap, concept);
// TODO Combine the concept with the geoConcept...
//var serviceHash = sparqlService.getStateHash();
//var geoConceptHash = geoMap.getElementFactory().createElement().toString();
//console.log("[DEBUG] Query hash (including facets): " + hash);
var cacheEntry = this.hashToCache[hash];
if(!cacheEntry) {
cacheEntry = new ns.QuadTreeCache(sparqlService, geoMapFactory, concept, null, quadTreeConfig);
this.hashToCache[hash] = cacheEntry;
}
var nodePromise = cacheEntry.fetchData(bounds);
// Create a new view state object
var result = nodePromise.pipe(function(nodes) {
var r = new ns.ViewState(sparqlService, geoMap, concept, bounds, nodes);
return r;
});
return result;
}
});
ns.ViewStateFetcher.defaultQuadTreeConfig = {
maxItemsPerTileCount: 1000,
maxGlobalItemCount: 5000
};
})();