GpsGate Server JavaScript API

Vec2  1.0.0

GpsGate Server JavaScript API > Vec2 > vehiclemarker.js (source view)
Search:
 
Filters
/**
 * Copyright Franson Technology AB, Sweden, 2009
 * <br />
 * <a href="http://gpsgate.com/">http://gpsgate.com</a>, <a href="http://franson.com/">http://franson.com</a>
 * <br /><br />
 * author Fredrik Blomqvist
 *
 * @module Map
 *
 */

var Franson = Franson || {};
/*
 * namespace
 * //class Franson.Map
 * //static
 */
Franson.Map = Franson.Map || {};


/**
 * marker to be used in VT. includes textlabel and arrow marker
 * todo: inherit from Marker
 * todo: move to VT module
 * @param {Franson.GateUser} vehicle
 * @param {literal} [options]
 * @class Franson.Map.VehicleMarker
 * @extends Franson.Map.IOverlay
 * @constructor
 */
Franson.Map.VehicleMarker = function(vehicle, options)
{
	this._options = MochiKit.Base.setdefault(options, {
		hide: false, // initially hidden?
		markerType: 'arrow',
		showText: true,
		rotate: true,
		getLegendText: vehicle.getName()
		// todo: showTextLabel, iconType, font, fontSize, size/scale etc
	});

	// disable rotate for needle
	this._options.rotate = this._options.markerType == 'needle' ? false : this._options.rotate;

	/**
	 * @private @type Franson.GateUser
	 */
	this._vehicle = vehicle;
		this._vehicle._hidden = false; // force in a visible state, hackish but ok for now.
	/**
	 * group object that holds the arrow- and label-icon
	 * @private @type {dojox.gfx.Group/Shape}
	 */
	this._icon = null;
		// children to _icon but added as members for easy access
		this._arrowIcon = null;
		this._nameLabel = null;

	/**
	 * @private
	 */
	this._clickHandler = null;

	// todo: fwd more events? (click is handled in initialize)

	/**
	 * @private @type Franson.Map.Layer
	 */
	this._layer = null;
};


// methods
Franson.Map.VehicleMarker.prototype =
{
	/**
	 * Overlay interface
	 * todo: not quite ok with layer structure..
	 * @method initialize
	 * @param {Franson.Map.ILayer} layer
	 * @protected
	 */
	initialize: function(layer) // similar to GMap::initialize(map)
	{
		this._layer = layer;

		var projection = layer.getProjection();

		// todo: ugly.. (move this to GateUser?)
		// todo: better config of this
		var color = typeof(this._vehicle.attributes["MarkerColor"]) == 'undefined' ? '#000000' : '#' + this._vehicle.attributes["MarkerColor"].value;

		// group for convenience
		this._icon = this._layer.getRoot().createGroup();

		this._arrowIcon = this._options.markerType == 'arrow' ? Franson.Graphics.Shape.createArrowIcon(8, color, this._icon) : Franson.Graphics.Shape.createNeedleIcon(8, color, this._icon);

		if (this._options.showText)
		{
			var bbArrow = Franson.Graphics.calcBounds(this._arrowIcon);

			this._nameLabel = Franson.Graphics.Shape.createTextLabel(this._options.getLegendText(this._vehicle), {
				backgroundColor: color,
				// anchor to always be above the arrow (hmm, could perhaps make this dynamic depending on the arrow direction?)
				anchor: { x: bbArrow.w, y: bbArrow.h-5 }
			}, this._icon);
		}

		Franson.Graphics.setTitle(this._icon, this._vehicle.getName());

		// indicate clickability
		Franson.Graphics.setCursor(this._icon, Franson.Util.isIE() ? 'hand' : 'pointer');

		this._clickHandler = this._icon.connect('onclick', this, function(e)
		{
			this._icon.moveToFront(); // or make this a logic on the client side?
			var latlng = this._vehicle.getTrackPoint().pos;
			signal(this, 'onclick', latlng);
		});

		if (this._options.hide)
			this.hide();
	},

	/**
	 * @method getIcon
	 * @return {dojox.gfx.Shape}
	 */
	getIcon: function()
	{
		return this._icon;
	},

	/**
	 * destructor
	 * @method destroy
	 */
	destroy: function()
	{
		this.remove();
		disconnectAll(this);
		this._arrowIcon = this._nameLabel = this._icon = null;
	},

	/**
	 * Overlay interface
	 * @method redraw
	 * @param {boolean} force
	 * @protected
	 */
	redraw: function(force)
	{
		if (!force || this._vehicle._hidden)
			return;

		var tp = this._vehicle.getTrackPoint();

		var cullBounds = this._layer.getSurface()._getCullBounds();

		if (cullBounds.containsLatLng(tp.pos))
		{
			var pos = this._layer.getProjection().fromLatLngToDivPixel(tp.pos); // observe that we delay setting the position even if hidden to not crash IE/VML..

			Franson.Graphics.setPosition(this._icon, pos);

			if (this._options.rotate)
			{
				var rot = Franson.Math.degToRad(tp.vel.heading);
				this._arrowIcon.setTransform(dojox.gfx.matrix.rotate(rot));
			}

			Franson.Graphics.show(this._icon); // not same as this.show()!
		}
		else
		{
			Franson.Graphics.hide(this._icon); // not same as this.hide()!
		}
	},

	/**
	 * ok? vehicle is optional (or take just a TrackPoint?)
	 * @method update
	 * @param {Franson.GateUser} [vehicle] if not supplied uses the initially set vehicle
	 */
	update: function(vehicle)
	{
		this._vehicle = vehicle || this._vehicle;

		this.redraw(true);
	},

	/**
	 * <a href="http://code.google.com/apis/maps/documentation/reference.html#GOverlay.remove">GOverlay.remove</a>
	 * @protected
	 */
	remove: function()
	{
		if (this._icon)
		{
			if (this._clickHandler != null)
			{
				this._icon.disconnect(this._clickHandler);
				this._clickHandler = null;
			}

			this._icon.removeShape();
			signal(this, 'onremove');
		}
	},

	/**
	 * @method hide
	 */
	hide: function()
	{
		if (!this._vehicle._hidden)
		{
			this._vehicle._hidden = true;
			Franson.Graphics.hide(this._icon);
		}
		// let event fire anyway
		signal(this, 'onvisibilitychanged', false);
	},

	/**
	 * @method show
	 */
	show: function()
	{
		if (this._vehicle._hidden)
		{
			this._vehicle._hidden = false;
			Franson.Graphics.show(this._icon);
			this.redraw(true); // position isn't updated when hidden
		}
		// let event fire anyway
		signal(this, 'onvisibilitychanged', true);
	},

	/**
	 * @method isHidden
	 * @return {boolean}
	 */
	isHidden: function()
	{
		return this._vehicle._hidden;
	//	return Franson.Graphics.isHidden(this._icon);
	},

	/**
	 * @method setStatus
	 * @param {boolean} active
	 */
	setStatus: function(active)
	{
		this._arrowIcon.setActive(active);
		if (this._nameLabel != null)
			this._nameLabel.setActive(active);
	}
}; // Franson.Map.VehicleMarker.prototype


/**
 * fired in hide() and show()
 * @event onvisibilitychanged
 * @param {boolean} visible
 */

/**
 * fired in remove()
 * @event onremove
 */

/**
 * @event onclick
 * @param {LatLng} latlng
 */

Copyright © 2009 Franson Technology AB, Sweden. All rights reserved.