infusion-code/angular-maps

View on GitHub
src/models/bing/bing-label.ts

Summary

Maintainability
C
7 hrs
Test Coverage
import { BingMapService } from '../../services/bing/bing-map.service';
import { BingConversions } from '../../services/bing/bing-conversions';
import { ILabelOptions } from '../../interfaces/ilabel-options';
import { MapLabel } from '../map-label';
import { Extender } from '../extender';

let id: number = 0;

/**
 * Implements map a labled to be placed on the map.
 *
 * @export
 */
export class BingMapLabel extends MapLabel {

    /**
     * Returns the default label style for the platform
     *
     * @readonly
     * @abstract
     * @memberof BingMapLabel
     */
    public get DefaultLabelStyle(): ILabelOptions {
        return {
            fontSize: 12,
            fontFamily: 'sans-serif',
            fontColor: '#ffffff',
            strokeWeight: 2,
            strokeColor: '#000000'
        };
    }

    ///
    /// Constructor
    ///

    /**
     * Creates a new MapLabel
     * @param options Optional properties to set.
     */
    constructor(options: { [key: string]: any }) {
        options.fontSize = options.fontSize || 12;
        options.fontColor = options.fontColor || '#ffffff';
        options.strokeWeight = options.strokeWeight || 2;
        options.strokeColor = options.strokeColor || '#000000';
        super(options);
        (<any>this)._options.beneathLabels = false;
    }

    ///
    /// Public methods
    ///

    /**
     * Gets the value of a setting.
     *
     * @param key - Key specifying the setting.
     * @returns - The value of the setting.
     * @memberof BingMapLabel
     * @method
     */
    public Get(key: string): any {
        return (<any>this)[key];
    }

    /**
     * Gets the map associted with the label.
     *
     * @memberof BingMapLabel
     * @method
     */
    public GetMap(): Microsoft.Maps.Map {
        return (<any>this).getMap();
    }

    /**
     * Set the value for a setting.
     *
     * @param key - Key specifying the setting.
     * @param val - The value to set.
     * @memberof BingMapLabel
     * @method
     */
    public Set(key: string, val: any): void {
        if (key === 'position' && !val.hasOwnProperty('altitude') && val.hasOwnProperty('latitude') && val.hasOwnProperty('longitude')) {
            val = new Microsoft.Maps.Location(val.latitude, val.longitude);
        }
        if (this.Get(key) !== val) {
            (<any>this)[key] = val;
            this.Changed(key);
        }
    }

    /**
     * Sets the map for the label. Settings this to null remove the label from hte map.
     *
     * @param map - Map to associated with the label.
     * @memberof BingMapLabel
     * @method
     */
    public SetMap(map: Microsoft.Maps.Map): void {
        const m: Microsoft.Maps.Map = this.GetMap();
        if (map === m) { return; }
        if (m) {
            m.layers.remove(this);
        }
        if (map != null) {
            map.layers.insert(this);
        }
    }

    /**
     * Applies settings to the object
     *
     * @param options - An object containing the settings key value pairs.
     * @memberof BingMapLabel
     * @method
     */
    public SetValues(options: { [key: string]: any }): void {
        const p: Array<string> = new Array<string>();
        for (const key in options) {
            if (key !== '') {
                if (key === 'position' && !options[key].hasOwnProperty('altitude') &&
                    options[key].hasOwnProperty('latitude') && options[key].hasOwnProperty('longitude')) {
                    options[key] = new Microsoft.Maps.Location(options[key].latitude, options[key].longitude);
                }
                if (this.Get(key) !== options[key]) {
                    (<any>this)[key] = options[key];
                    p.push(key);
                }
            }
        }
        if (p.length > 0) { this.Changed(p); }
    }

    ///
    /// Protected methods
    ///

    /**
     * Draws the label on the map.
     * @memberof BingMapLabel
     * @method
     * @protected
     */
    protected Draw(): void {
        const visibility: string = this.GetVisible();
        const m: Microsoft.Maps.Map = this.GetMap();
        if (!this._canvas) { return; }
        if (!m) { return; }
        const style: CSSStyleDeclaration = this._canvas.style;
        if (visibility !== '') {
            // label is not visible, don't calculate positions etc.
            style['visibility'] = visibility;
            return;
        }

        let offset: Microsoft.Maps.Point = this.Get('offset');
        const latLng: Microsoft.Maps.Location = this.Get('position');
        if (!latLng) { return; }
        if (!offset) { offset = new Microsoft.Maps.Point(0, 0); }

        const pos: Microsoft.Maps.Point = <Microsoft.Maps.Point>m.tryLocationToPixel(
            latLng,
            Microsoft.Maps.PixelReference.control);
        style['top'] = (pos.y + offset.y) + 'px';
        style['left'] = (pos.x + offset.x) + 'px';
        style['visibility'] = visibility;
    }

    /**
     * Delegate called when the label is added to the map. Generates and configures
     * the canvas.
     *
     * @memberof BingMapLabel
     * @method
     * @protected
     */
    protected OnAdd() {
        this._canvas = document.createElement('canvas');
        this._canvas.id = `xMapLabel${id++}`;
        const style: CSSStyleDeclaration = this._canvas.style;
        style.position = 'absolute';

        const ctx: CanvasRenderingContext2D = this._canvas.getContext('2d');
        ctx.lineJoin = 'round';
        ctx.textBaseline = 'top';

        (<any>this).setHtmlElement(this._canvas);
    }

    ///
    /// Private methods
    ///

    /**
     * Delegate callled when the label is loaded
     * @memberof BingMapLabel
     * @method
     */
    private OnLoad() {
        Microsoft.Maps.Events.addHandler(this.GetMap(), 'viewchange', () => {
            this.Changed('position');
        });
        this.DrawCanvas();
        this.Draw();
    }
}

/**
 * Helper function to extend the CustomOverlay into the MapLabel
 *
 * @export
 * @method
 */
export function MixinMapLabelWithOverlayView() {
    new Extender(BingMapLabel)
    .Extend(new Microsoft.Maps.CustomOverlay())
    .Map('onAdd', 'OnAdd')
    .Map('onLoad', 'OnLoad')
    .Map('onRemove', 'OnRemove');
}