/**
* <span>
* Copyright Franson Technology AB, Sweden, 2009
* </span>
* <a href="http://gpsgate.com/">http://gpsgate.com</a>, <a href="http://franson.com/">http://franson.com</a>
* <span>
* author Fredrik Blomqvist
* </span>
*
* @module Map
*
*/
var Franson = Franson || {};
/*
* namespace
* //class Franson.Map
* //static
*/
Franson.Map = Franson.Map || {};
/**
* Layer is essentially an overlay but with grouping and ordering etc.<br />
* note that based on this interface you could create more specialized domain-specific layers (DS interface, automatic conversion from DS types to markers etc)<br />
* todo: should we try to abstract more? so we can create layers not using actual SVG/VML nodes.. (to wrap map-native overlays for example, traffic-info etc)
* todo: more events..
* @param {string} id used to identity the layer (<code>map.getLayer('layerId')</code>)
* @param {string} name what will typically (probably) be displayed in the GUI
* @param {literal} [options]
* @class Franson.Map.Layer
* @extends Franson.Map.ILayer
* @constructor
*/
Franson.Map.Layer = function(id, name, options)
{
/**
* @type string
*/
this.id = id;
/**
* @private @type {string}
*/
this._name = name;
this._options = MochiKit.Base.setdefault(options, { // todo: expose a getOptions?
// ? y-ordering (N->S), z-index etc
description: ''
});
/**
* @private
* @type Franson.Map.MapSurface
*/
this._mapSurface = null;
/**
* @private
* @type dojox.gfx.Group
*/
this._root = null;
/**
* @private
* @type Franson.Map.IOverlay[]
*/
this._overlays = []; // todo: move this away from here if we wan't to use this as a baseclass. (custom layers may need other storage)
/**
* @private
* @type Franson.Map.IMap
*/
this._map = null; // .. currently "forced" in by map.addLayer for now.. (should perhaps change initialize to receive a map instead)
/**
* @private
* @type boolean
*/
this._hidden = false;
};
// methods
Franson.Map.Layer.prototype =
{
/**
* IOverlay (+ root)
* root is the "handle" we get from mapSurface to attach to
*/
initialize: function(mapSurface, root)
{
this._mapSurface = mapSurface;
this._root = root;
},
/**
* @method getSurface
* @return {Franson.Map.MapSurface}
*/
getSurface: function()
{
return this._mapSurface;
},
/**
* ok? remove?
* @method getMap
* @return {Franson.Map.IMap}
*/
getMap: function()
{
return this._map;
},
/**
* @method getRooot
* @return {dojox.gfx.Group}
*/
getRoot: function()
{
return this._root;
},
/**
* normally (but not necessarily) same as map's projection
* @method getProjection
* @return {Projection}
*/
getProjection: function()
{
// return this.getSurface().getProjection(); // allowed to override this
return this.getMap().getProjection();
},
/**
* IOverlay
* @method redraw
* @param {boolean} [force=false]
* @protected
*/
redraw: function(force)
{
if (!this._hidden)
Franson.Graphics.hide(this.getRoot());
forEach(this._overlays, MochiKit.Base.methodcaller('redraw', force));
if (!this._hidden)
Franson.Graphics.show(this.getRoot());
},
/* getBounds: function()
{
// todo: should be a union (hull) of the visible overlays' bounds
return null;
},
*/
/**
* part of IOverlay
* @method remove
* @protected
*/
remove: function()
{
this._root.removeShape();
// todo: event?
},
/**
* destructor
* @method destroy
* @param {boolean} [deep=false] <code>true</code> to destroy layers also
*/
destroy: function(deep)
{
deep = deep || false;
if (deep)
this._destroyOverlays();
else
this.clearOverlays();
this.remove();
disconnectAll(this);
this._root = null;
this._mapSurface = null;
this._map = null;
},
/**
* @method getName
* @return {string}
*/
getName: function()
{
return this._name;
},
/**
* @method setName
* @param {string} name
*/
setName: function(name)
{
this._name = name;
},
/**
* @method addOverlay
* @param {Franson.Map.IOverlay} overlay
*/
addOverlay: function(overlay)
{
overlay.initialize(this);
this._overlays.push(overlay);
overlay.redraw(true);
},
/**
* @method removeOverlay
* @param {Franson.Map.IOverlay} overlay
*/
removeOverlay: function(overlay)
{
for (var i = 0; i < this._overlays.length; ++i)
{
if (this._overlays[i] == overlay)
{
this._overlays.splice(i, 1);
break;
}
}
overlay.remove();
disconnectAll(overlay); // hmm, this is quite useful I'd say. but GMap doesn't do this..
},
/**
* @method clearOverlays
*/
clearOverlays: function()
{
forEach(this._overlays, function(overlay) // ! can't use forEach(..this.removeOverlay) since it modifies the list!
{
overlay.remove();
disconnectAll(overlay);
});
this._overlays = [];
},
// todo: add a getOverlays() also? GMap doesn't have one but we've exposed a getLayers() in mapSurface for example.
/**
* @method hide
*/
hide: function()
{
if (!this._hidden)
{
Franson.Graphics.hide(this._root);
this._hidden = true;
}
// todo: fire event..
},
/**
* @method show
*/
show: function()
{
if (this._hidden)
{
Franson.Graphics.show(this._root);
this._hidden = false;
}
},
/**
* @method isHidden
* @return {boolean}
*/
isHidden: function()
{
return this._hidden;
// return Franson.Graphics.isHidden(this._root);
}
}; // Franson.Map.Layer.prototype