Commit b041deba authored by Piotr Gawron's avatar Piotr Gawron
Browse files

refactor: operations on markers on map moved to separate class

parent 7154070b
......@@ -14,6 +14,8 @@ var PointInfoWindow = require('./window/PointInfoWindow');
var ReactionInfoWindow = require('./window/ReactionInfoWindow');
var ReactionSurface = require('./surface/ReactionSurface');
var MarkerSurfaceCollection = require('./marker/MarkerSurfaceCollection');
/**
* Default constructor.
*/
......@@ -53,6 +55,8 @@ function AbstractCustomMap(model, options) {
// array with info windows for reactions
this._reactionInfoWindow = [];
this._markerSurfaceCollection = new MarkerSurfaceCollection({map: this});
// this is google.maps.drawing.DrawingManager that will allow user to draw
// elements in the client
this._drawingManager = null;
......@@ -76,6 +80,10 @@ function AbstractCustomMap(model, options) {
AbstractCustomMap.prototype = Object.create(ObjectWithListeners.prototype);
AbstractCustomMap.prototype.constructor = AbstractCustomMap;
AbstractCustomMap.prototype.getMarkerSurfaceCollection = function () {
return this._markerSurfaceCollection;
};
/**
* Assigns layouts with images to the google map (which set of images should be
* used by google maps api for which layout).
......@@ -650,7 +658,7 @@ AbstractCustomMap.prototype._showSelectedLayout = function (layoutId, index, len
return self.getTopMap().callListeners("onBioEntityClick", element);
}],
customized: (length === 1)
}).then(function(result){
}).then(function (result) {
surface = result;
self.selectedLayoutOverlays[layoutId].push(surface);
surface.show();
......
......@@ -6,10 +6,6 @@ var logger = require('../logger');
var Functions = require('../Functions');
var AbstractCustomMap = require('./AbstractCustomMap');
var AbstractMarker = require('./marker/AbstractMarker');
var AbstractSurfaceElement = require('./surface/AbstractSurfaceElement');
var AliasMarker = require('./marker/AliasMarker');
var AliasSurface = require('./surface/AliasSurface');
var Alias = require('./data/Alias');
var CommentDialog = require('../gui/CommentDialog');
var ControlType = require('./ControlType');
......@@ -18,10 +14,7 @@ var GuiConnector = require('../GuiConnector');
var IdentifiedElement = require('./data/IdentifiedElement');
var LayoutData = require('./data/LayoutData');
var PointData = require('./data/PointData');
var PointMarker = require('./marker/PointMarker');
var Reaction = require('./data/Reaction');
var ReactionMarker = require('./marker/ReactionMarker');
var ReactionSurface = require('./surface/ReactionSurface');
var ReferenceGenome = require('./data/ReferenceGenome');
var SecurityError = require('../SecurityError');
var Submap = require('./Submap');
......@@ -243,11 +236,6 @@ CustomMap.prototype.registerDbOverlay = function (dbOverlay) {
this.overlayCollections[dbOverlay.getName()] = dbOverlay;
dbOverlay.markers = {
ALIAS: [],
REACTION: [],
POINT: []
};
dbOverlay.mapOverlays = {
ALIAS: [],
REACTION: [],
......@@ -334,20 +322,14 @@ CustomMap.prototype.refreshMarkers = function (force) {
};
CustomMap.prototype.refreshOverlayMarkers = function (overlay, force) {
var self = this;
logger.debug("Refresh overlay: " + overlay.name);
if (!this.isMarkerOptimization() || force) {
for (var markerType in overlay.markers) {
if (overlay.markers.hasOwnProperty(markerType)) {
var markers = overlay.markers[markerType];
for (var key in markers) {
if (markers.hasOwnProperty(key)) {
var marker = markers[key];
marker.hide();
marker.show();
}
}
}
self.getMarkerSurfaceCollection().refreshOverlayMarkers(overlay);
var submaps = self.getSubmaps();
for (var i = 0; i < submaps.length; i++) {
submaps[i].getMarkerSurfaceCollection().refreshOverlayMarkers(overlay);
}
}
};
......@@ -702,18 +684,22 @@ CustomMap.prototype.renderOverlayCollection = function (params) {
return Promise.each(elements, function (element) {
var icon = element.getIcon();
if (icon !== null && icon !== undefined) {
return self.createMarkerForDbOverlay(element, overlayCollection).then(function (marker) {
return self.getSubmapById(element.getModelId()).getMarkerSurfaceCollection().createMarkerForDbOverlay(element, overlayCollection).then(function (marker) {
markers.push(marker);
});
} else {
return self.createSurfaceForDbOverlay(element, overlayCollection).then(function (mapOverlay) {
return self.getSubmapById(element.getModelId()).getMarkerSurfaceCollection().createSurfaceForDbOverlay(element, overlayCollection).then(function (mapOverlay) {
markers.push(mapOverlay);
});
}
});
}).then(function () {
self.removeUnmodifiedMarkersAndSurfaces(markers, overlayCollection);
self.getMarkerSurfaceCollection().removeUnmodifiedMarkersAndSurfaces(markers, overlayCollection);
var submaps = self.getSubmaps();
for (var i = 0; i < submaps.length; i++) {
submaps[i].getMarkerSurfaceCollection().removeUnmodifiedMarkersAndSurfaces(markers, overlayCollection);
}
return Promise.each(elements, function (element) {
var infoWindow = self.getInfoWindowForIdentifiedElement(element);
......@@ -733,56 +719,6 @@ CustomMap.prototype.renderOverlayCollection = function (params) {
});
};
CustomMap.prototype.removeUnmodifiedMarkersAndSurfaces = function (modifiedMarkersAndSurfaces, dbOverlay) {
var modifiedMarkers = {
"ALIAS": [],
"REACTION": [],
"POINT": [],
};
var modifiedSurfaces = {
"ALIAS": [],
"REACTION": [],
"POINT": [],
};
for (var i = 0; i < modifiedMarkersAndSurfaces.length; i++) {
var object = modifiedMarkersAndSurfaces[i];
var identifiedElement = object.getIdentifiedElement();
if (object instanceof AbstractSurfaceElement) {
modifiedSurfaces[identifiedElement.getType()][identifiedElement.getId()] = true;
} else if (object instanceof AbstractMarker) {
modifiedMarkers[identifiedElement.getType()][identifiedElement.getId()] = true;
} else {
throw new Error("Unknown class type: " + object.prototype.name);
}
}
var markerType, key;
for (markerType in dbOverlay.markers) {
if (dbOverlay.markers.hasOwnProperty(markerType)) {
var markers = dbOverlay.markers[markerType];
for (key in markers) {
if (markers.hasOwnProperty(key) && !modifiedMarkers[markerType][key]) {
markers[key].setMap(null);
delete markers[key];
}
}
}
}
for (markerType in dbOverlay.mapOverlays) {
if (dbOverlay.mapOverlays.hasOwnProperty(markerType)) {
var mapOverlays = dbOverlay.mapOverlays[markerType];
for (key in mapOverlays) {
if (mapOverlays.hasOwnProperty(key) && !modifiedSurfaces[markerType][key]) {
mapOverlays[key].setMap(null);
delete mapOverlays[key];
}
}
}
}
};
/**
* Opens {@link AbstractInfoWindow} for a marker.
*
......@@ -1206,90 +1142,6 @@ CustomMap.prototype.getVisibleDataOverlays = function () {
return Promise.all(dataOverlayPromises);
};
CustomMap.prototype.createMarkerForDbOverlay = function (element, dbOverlay) {
var self = this;
var result = dbOverlay.markers[element.getType()][element.getId()];
if (result !== undefined) {
result.updateIdentifiedElement(element);
return Promise.resolve(result);
}
var submap = self.getSubmapById(element.getModelId());
var MarkerConstructor = null;
if (element.getType() === "ALIAS") {
MarkerConstructor = AliasMarker;
} else if (element.getType() === "REACTION") {
MarkerConstructor = ReactionMarker;
} else if (element.getType() === "POINT") {
MarkerConstructor = PointMarker;
} else {
throw new Error("Unknown type of the element in overlay: " + element.type);
}
result = new MarkerConstructor({
element: element,
map: submap,
onClick: [function () {
return self._openInfoWindowForIdentifiedElement(element, result.getGoogleMarker());
}, function () {
return self.callListeners("onBioEntityClick", element);
}]
});
return result.init().then(function () {
dbOverlay.markers[element.getType()][element.getId()] = result;
return result;
});
};
CustomMap.prototype.createSurfaceForDbOverlay = function (element, dbOverlay) {
var self = this;
var result = dbOverlay.mapOverlays[element.getType()][element.getId()];
if (result !== undefined) {
result.updateIdentifiedElement(element);
return Promise.resolve(result);
}
var map = self.getSubmapById(element.getModelId());
if (element.getType() === "ALIAS") {
return AliasSurface.createFromIdentifiedElement({
element: element,
map: self,
onClick: [function () {
return self.openInfoWindowForIdentifiedElement(element, result.getGoogleMarker());
}, function () {
return self.callListeners("onBioEntityClick", element);
}]
}).then(function (surface) {
result = surface;
dbOverlay.mapOverlays[element.getType()][element.getId()] = result;
return result;
});
} else if (element.getType() === "REACTION") {
return map.getModel().getReactionById(element.getId()).then(function (reactionData) {
return ReactionSurface.create({
reaction: reactionData,
map: map,
customized: true,
color: element.getColor(),
onClick: [function () {
return self.openInfoWindowForIdentifiedElement(element, result.getGoogleMarker());
}, function () {
return self.callListeners("onBioEntityClick", element);
}]
}).then(function (surface) {
result = surface;
result.show();
dbOverlay.mapOverlays[element.getType()][element.getId()] = result;
return result;
});
});
} else if (element.getType() === "POINT") {
throw new Error("Not implemented");
} else {
throw new Error("Unknown type of the element in overlay: " + element.type);
}
};
/**
* Opens {@link AbstractInfoWindow} for a marker.
......
"use strict";
var AbstractMarker = require('./AbstractMarker');
var AliasMarker = require('./AliasMarker');
var IdentifiedElement = require('../data/IdentifiedElement');
var PointMarker = require('./PointMarker');
var ReactionMarker = require('./ReactionMarker');
var AbstractSurfaceElement = require('../surface/AbstractSurfaceElement');
var AliasSurface = require('../surface/AliasSurface');
var ReactionSurface = require('../surface/ReactionSurface');
// noinspection JSUnusedLocalSymbols
var logger = require('../../logger');
var Promise = require("bluebird");
var ObjectWithListeners = require('../../ObjectWithListeners');
function MarkerSurfaceCollection(params) {
var self = this;
ObjectWithListeners.call(this);
self._markerOverlaysPerType = {
ALIAS: [],
REACTION: [],
POINT: []
};
self._surfaceOverlaysPerType = {
ALIAS: [],
REACTION: [],
POINT: []
};
self.setMap(params.map);
}
MarkerSurfaceCollection.prototype = Object.create(ObjectWithListeners.prototype);
MarkerSurfaceCollection.prototype.constructor = MarkerSurfaceCollection;
MarkerSurfaceCollection.prototype.setMap = function (map) {
if (map === undefined) {
throw new Error("Map must be defined");
}
this._map = map;
};
MarkerSurfaceCollection.prototype.getMap = function () {
return this._map;
};
MarkerSurfaceCollection.prototype.refreshOverlayMarkers = function (overlay) {
var self = this;
var markerOverlaysPerType = self._markerOverlaysPerType;
for (var markerType in markerOverlaysPerType) {
if (markerOverlaysPerType.hasOwnProperty(markerType)) {
var markers = markerOverlaysPerType[markerType][overlay.getName()];
if (markers !== undefined) {
for (var key in markers) {
if (markers.hasOwnProperty(key)) {
var marker = markers[key];
marker.hide();
marker.show();
}
}
}
}
}
};
MarkerSurfaceCollection.prototype.createMarkerForDbOverlay = function (element, dbOverlay) {
var self = this;
var result = self.getMarker({element: element, overlay: dbOverlay});
if (result !== undefined) {
result.updateIdentifiedElement(element);
return Promise.resolve(result);
}
var MarkerConstructor = null;
if (element.getType() === "ALIAS") {
MarkerConstructor = AliasMarker;
} else if (element.getType() === "REACTION") {
MarkerConstructor = ReactionMarker;
} else if (element.getType() === "POINT") {
MarkerConstructor = PointMarker;
} else {
throw new Error("Unknown type of the element in overlay: " + element.type);
}
result = new MarkerConstructor({
element: element,
map: self.getMap(),
onClick: [function () {
return self.getMap()._openInfoWindowForIdentifiedElement(element, result.getGoogleMarker());
}, function () {
return self.getMap().callListeners("onBioEntityClick", element);
}]
});
return result.init().then(function () {
self.putMarker({element: element, overlay: dbOverlay}, result);
return result;
});
};
MarkerSurfaceCollection.prototype.createSurfaceForDbOverlay = function (element, dbOverlay) {
var self = this;
var result = self.getSurface({element: element, overlay: dbOverlay});
if (result !== undefined) {
result.updateIdentifiedElement(element);
return Promise.resolve(result);
}
var map = self.getMap();
var onclickFunctions = [function () {
return self.getMap().openInfoWindowForIdentifiedElement(element, result.getGoogleMarker());
}, function () {
return self.getMap().callListeners("onBioEntityClick", element);
}];
if (element.getType() === "ALIAS") {
return AliasSurface.createFromIdentifiedElement({
element: element,
map: map,
onClick: onclickFunctions
}).then(function (surface) {
result = surface;
self.putSurface({element: element, overlay: dbOverlay}, result);
return result;
});
} else if (element.getType() === "REACTION") {
return map.getModel().getReactionById(element.getId()).then(function (reactionData) {
return ReactionSurface.create({
reaction: reactionData,
map: map,
customized: true,
color: element.getColor(),
onClick: onclickFunctions
}).then(function (surface) {
result = surface;
result.show();
self.putSurface({element: element, overlay: dbOverlay}, result);
return result;
});
});
} else if (element.getType() === "POINT") {
throw new Error("Not implemented");
} else {
throw new Error("Unknown type of the element in overlay: " + element.type);
}
};
MarkerSurfaceCollection.prototype.getMarker = function (params) {
var element = new IdentifiedElement(params.element);
var overlay = params.overlay;
var markerOverlaysPerType = this._markerOverlaysPerType;
var overlayMarkers = markerOverlaysPerType[element.getType()][overlay.getName()];
if (overlayMarkers === undefined) {
markerOverlaysPerType[element.getType()][overlay.getName()] = [];
overlayMarkers = markerOverlaysPerType[element.getType()][overlay.getName()];
}
return overlayMarkers[element.getId()];
};
MarkerSurfaceCollection.prototype.getMarkers = function () {
var result = [];
var markerOverlaysPerType = this._markerOverlaysPerType;
for (var markerType in markerOverlaysPerType) {
if (markerOverlaysPerType.hasOwnProperty(markerType)) {
var markersByType = markerOverlaysPerType[markerType];
for (var overlayName in markersByType) {
if (markersByType.hasOwnProperty(overlayName)) {
var markers = markersByType[overlayName];
for (var key in markers) {
if (markers.hasOwnProperty(key)) {
result.push(markers[key]);
}
}
}
}
}
}
return result;
};
MarkerSurfaceCollection.prototype.getSurfaces = function () {
var result = [];
var surfaceOverlaysPerType = this._surfaceOverlaysPerType;
for (var markerType in surfaceOverlaysPerType) {
if (surfaceOverlaysPerType.hasOwnProperty(markerType)) {
var markersByType = surfaceOverlaysPerType[markerType];
for (var overlayName in markersByType) {
if (markersByType.hasOwnProperty(overlayName)) {
var markers = markersByType[overlayName];
for (var key in markers) {
if (markers.hasOwnProperty(key)) {
result.push(markers[key]);
}
}
}
}
}
}
return result;
};
MarkerSurfaceCollection.prototype.putMarker = function (params, marker) {
var element = new IdentifiedElement(params.element);
var overlay = params.overlay;
var markerOverlaysPerType = this._markerOverlaysPerType;
var overlayMarkers = markerOverlaysPerType[element.getType()][overlay.getName()];
if (overlayMarkers === undefined) {
markerOverlaysPerType[element.getType()][overlay.getName()] = [];
overlayMarkers = markerOverlaysPerType[element.getType()][overlay.getName()];
}
overlayMarkers[element.getId()] = marker;
};
MarkerSurfaceCollection.prototype.getSurface = function (params) {
var element = new IdentifiedElement(params.element);
var overlay = params.overlay;
var surfaceOverlaysPerType = this._surfaceOverlaysPerType;
var overlaySurfaces = surfaceOverlaysPerType[element.getType()][overlay.getName()];
if (overlaySurfaces === undefined) {
surfaceOverlaysPerType[element.getType()][overlay.getName()] = [];
overlaySurfaces = surfaceOverlaysPerType[element.getType()][overlay.getName()];
}
return overlaySurfaces[element.getId()];
};
MarkerSurfaceCollection.prototype.putSurface = function (params, surface) {
var element = new IdentifiedElement(params.element);
var overlay = params.overlay;
var surfaceOverlaysPerType = this._surfaceOverlaysPerType;
var overlaySurfaces = surfaceOverlaysPerType[element.getType()][overlay.getName()];
if (overlaySurfaces === undefined) {
surfaceOverlaysPerType[element.getType()][overlay.getName()] = [];
overlaySurfaces = surfaceOverlaysPerType[element.getType()][overlay.getName()];
}
overlaySurfaces[element.getId()] = surface;
};
MarkerSurfaceCollection.prototype.removeUnmodifiedMarkersAndSurfaces = function (modifiedMarkersAndSurfaces, dbOverlay) {
var modifiedMarkers = {
"ALIAS": [],
"REACTION": [],
"POINT": []
};
var modifiedSurfaces = {
"ALIAS": [],
"REACTION": [],
"POINT": []
};
for (var i = 0; i < modifiedMarkersAndSurfaces.length; i++) {
var object = modifiedMarkersAndSurfaces[i];
var identifiedElement = object.getIdentifiedElement();
if (object instanceof AbstractSurfaceElement) {
modifiedSurfaces[identifiedElement.getType()][identifiedElement.getId()] = true;
} else if (object instanceof AbstractMarker) {
modifiedMarkers[identifiedElement.getType()][identifiedElement.getId()] = true;
} else {
throw new Error("Unknown class type: " + object.prototype.name);
}
}
var markerType, key;
var markerOverlaysPerType = this._markerOverlaysPerType;
for (markerType in markerOverlaysPerType) {
if (markerOverlaysPerType.hasOwnProperty(markerType)) {
var markers = markerOverlaysPerType[markerType][dbOverlay.getName()];
for (key in markers) {
if (markers.hasOwnProperty(key) && !modifiedMarkers[markerType][key]) {
markers[key].setMap(null);
delete markers[key];
}
}
}
}
var surfaceOverlaysPerType = this._surfaceOverlaysPerType;
for (markerType in surfaceOverlaysPerType) {
if (surfaceOverlaysPerType.hasOwnProperty(markerType)) {
var mapOverlays = surfaceOverlaysPerType[markerType][dbOverlay.getName()];
for (key in mapOverlays) {
if (mapOverlays.hasOwnProperty(key) && !modifiedSurfaces[markerType][key]) {
mapOverlays[key].setMap(null);
delete mapOverlays[key];
}
}
}
}
};
module.exports = MarkerSurfaceCollection;
......@@ -279,7 +279,6 @@ ReactionSurface.create = function (params) {
promise = functions.overlayToColor(overlayData);
}
return promise.then(function (color) {
logger.debug(color);
if (color === undefined) {
color = "#0000FF"</