All files MapInformation.js

100% Statements 42/42
91.67% Branches 22/24
100% Functions 1/1
100% Lines 42/42
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 1701x     1x     1x     1x     1x     1x     1x                             17x               20x                 69x 23x 12x 12x 12x                   12x 12x 12x 12x   23x               17x               12x 12x               7x 7x 7x 7x 7x 3x   7x                 6x 6x                 3x 3x 3x               2x 2x 2x               5x 5x                 5x             10x                 1x      
import {
    Events
} from './Events.js';
import {
    Helper
} from './Helper.js';
import {
    Publisher
} from './Publisher.js';
import {
    LatLng
} from './LatLng.js';
import {
    Bounds
} from './Bounds.js';
import {
    Point
} from './Point.js';
import {
    Rectangle
} from './Rectangle.js';
 
/**
 * @author Michael Duve <mduve@designmail.net>
 * @file stores and handles all information for a map
 * @copyright Michael Duve 2016
 */
export class MapInformation {
 
    /**
     * Returns the current distorted viewport
     */
    get offsetToCenter() {
        return (this.data.viewport.width - this.data.viewport.width * this.data.distortionFactor) / 2;
    }
 
    /**
     * how many pixels per lat and lng
     * @return {Point} pixels per lat/lng
     */
    get pixelPerLatLng() {
        return new Point((this.data.view.width / this.data.bounds.width) || 0, (this.data.view.height / this.data.bounds.height) || 0);
    }
 
    /**
     * @constructor
     * @param {Number} id=0 - id of MapInformation instance
     * @param {String} path="./" - path to data
     * @return {MapInformation} singleton instance of MapInformation for chaining
     */
    constructor(id = 0, path = "./") {
        if (!MapInformation.instances[id]) {
            this.id = id;
            this.path = path;
            this.data = {
                center: new LatLng(),
                view: new Rectangle(),
                viewport: new Rectangle(),
                distortionFactor: 1,
                offsetToCenter: 0,
                bounds: new Bounds(),
                zoomFactor: 1,
                level: 0
            };
            this.data.offsetToCenter = this.offsetToCenter;
            this.eventManager = new Publisher(this.id);
            this.bindEvents();
            MapInformation.instances[id] = this;
        }
        return MapInformation.instances[id];
    }
 
    /**
     * gets current data
     * @return {Object} map information
     */
    get() {
        return this.data;
    }
 
    /**
     * bind all events
     * @return {MapInformation} instance of MapInformation for chaining
     */
    bindEvents() {
        this.eventManager.subscribe(Events.MapInformation.UPDATE, this.update.bind(this));
        return this;
    }
 
    /**
     * updates current information
     * @param  {Object} obj = {} - new data delivered
     * @return {MapInformation} instance of MapInformation for chaining
     */
    update(obj = {}) {
        const oldData = this.data;
        this.data = Object.assign({}, this.data, obj);
        const centerUpdateDone = (!oldData.center.equals(this.data.center)) ? this.centerUpdated() : false;
        if (!centerUpdateDone && !oldData.viewport.equals(this.data.viewport)) {
            this.updateOffsetToCenter();
        }
        return this;
    }
 
    /**
     * converts a Point to LatLng in view
     * @param  {Point} point - specified point to be converted
     * @return {LatLng} presentation of point in lat-lng system
     */
    convertPointToLatLng(point) {
        point.divide(this.pixelPerLatLng.x, this.pixelPerLatLng.y);
        return new LatLng(this.data.bounds.nw.lat - point.y, point.x + this.data.bounds.nw.lng);
    }
 
    /**
     * converts a LatLng to Point in view
     * @param  {LatLng} latlng - specified latlng to be converted
     * @return {Point} presentation of point in pixel system
     */
    convertLatLngToPoint(latlng) {
        const relativePosition = this.data.bounds.nw.clone.substract(latlng);
        relativePosition.multiply(this.pixelPerLatLng.y, this.pixelPerLatLng.x);
        return new Point(relativePosition.lng, relativePosition.lat).abs;
    }
 
    /**
     * center position was updated
     * @return {Boolean} information was updated
     */
    centerUpdated() {
        this.data.distortionFactor = this.getDistortionFactorForLatitude(this.data.center);
        this.updateOffsetToCenter();
        return true;
    }
 
    /**
     * offset to center was updated
     * @return {Boolean} information was updated
     */
    updateOffsetToCenter() {
        this.data.offsetToCenter = this.offsetToCenter;
        return true;
    }
 
    /**
     * get distortion factor for specified latitude
     * @param  {LatLng} latlng - lat/lng position
     * @return {Number} distortion factor
     */
    getDistortionFactorForLatitude(latlng) {
        return (Math.cos(Helper.toRadians(latlng.lat)));
    }
 
    /**
     * destroys singleton instance
     */
    destroy() {
        MapInformation.instances[this.id] = null;
    }
 
}
 
/**
 * singleton instance wrapper
 * @type {Object}
 */
MapInformation.instances = {
 
};