diff --git a/.gitignore b/.gitignore index 577a2ac..0509e2d 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,9 @@ typings/ *.code-workspace .history/ .vscode/ + + +# ignore generated contents- +/doc/out/* +**/thumbnails +**/thumbnail.png \ No newline at end of file diff --git a/assets/logos/iwm_logo_2015_twitter.png b/assets/logos/iwm_logo_2015_twitter.png new file mode 100644 index 0000000..5de9915 Binary files /dev/null and b/assets/logos/iwm_logo_2015_twitter.png differ diff --git a/dist/iwmlib.pixi.js b/dist/iwmlib.pixi.js index 3f1f5f2..1b81d9b 100644 --- a/dist/iwmlib.pixi.js +++ b/dist/iwmlib.pixi.js @@ -17444,7 +17444,7 @@ * @constructor * @param {Projection}[projection] - Specifies the projection of the map (e.g. Mercator Projection). * @param {object}[opts] - Addiditonal options. - * @param {[[minLat, minLng],[maxLat, maxLng]]}[opts.bounds] - Describes the minimum and maximum coordinates on the map + * @param {array}[opts.bounds] - Describes the minimum and maximum coordinates on the map in the form of {[[minLat, minLng],[maxLat, maxLng]]}. * @param {Point}[opts.translate] - Defines a translation, when clipping is not an option (e.g. when the whole world is shown, but translated.) */ constructor(projection, opts = {}) { @@ -17482,6 +17482,7 @@ /** * Transforms a pixel point on the map to a geographical coordinate. * + * @public * @param {{x,y} | PIXI.Point} point - A pixel position on the map. * @returns {{x,y} | PIXI.Point} - A geographical coordinate. * @memberof MapData @@ -17514,6 +17515,7 @@ /** * Transform a geographical coordinate to a pixel point on the map. * + * @public * @param {{x,y} | PIXI.Point} coordinates - A point in the form of {x:lat,y:lng}. * @returns {{x,y} | PIXI.Point} point - A pixel position on the map. * @memberof MapData @@ -17546,6 +17548,18 @@ return point } + + /** + * Get's the clipping of the map data. Clipping describes the + * piece of the map that is shown. E.g. if we just show a map of + * europe, then we have to set the clipping properly, otherwise + * the preojection would produce the wrong results when transforming + * from a point to coordinates or the other way around. + * + * @readonly + * @memberof MapData + * @returns {object} - Object that contains a min and max value of the clipping in form of: {min: {x,y}, max:{x,y}}. Where x and y are in between 0 and 1. + */ get clip() { let unclipped = { min: { x: 0, y: 0 }, @@ -17555,30 +17569,30 @@ return this.opts.clip ? this.opts.clip : unclipped } + /** - * Bounds to pixel transforms some bounds in form of {min:{x:minLat, y:minLng},max:{x:maxLat, y:maxLng}} - * to pixel coordinates. + * Returns the biggest viewport the mapdata allows. + * This is determined by the projecton or the clipping on the mapapp. * + * @readonly + * @memberof MapData */ - getBoundaries() { - // let min = this.toPixel(bounds.min) - // let max = this.toPixel(bounds.max) - - // Y values needs to be swapped, as PIXI has it's origin - // in the top-left corner and a regular map in the bottom-left corner. - let boundaries = { - min: { x: 0, y: 0 }, - max: { x: 1, y: 1 } - }; - - return boundaries - } - get maxViewport() { return this.opts.clip ? this.opts.clip : this.projection.maxViewport } } + + /** + * Special mapdata for DeepZoomMap objects. + * + * Note: It just transform the clipping parameter of the tiles config + * to the clipping of the mapapp. + * + * @export + * @class DeepZoomMapData + * @extends {MapData} + */ class DeepZoomMapData extends MapData { constructor(projection, tilesConfig, opts = {}) { if (tilesConfig.clip) { @@ -17773,10 +17787,18 @@ } flushHandlers() { - // this.onLoaded + this.onLoad.empty(); this.onTransform.empty(); } + /** + * Locks all transformations on the map. + * Single parameters can be set if necessary. False means the value is locked, true means they can be modified. + * + * @public + * @param {object} [{ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false }={}] + * @memberof GeoMap + */ lock({ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false } = {}) { if (this.image && this.image.scatter) { this.image.scatter.translatable = rotatable; @@ -17785,30 +17807,26 @@ this.image.scatter.rotatable = movableY; this.image.scatter.scalable = scalable; } - - // Issue #001: This causes the map to not be displayed at the correct position on - // map change. - // // Rotation does not yet work with the cover mechanism. - // //this.rotatable = false - // this.translatable = false - // this.scalable = false } + /** + * Unlocks all transformations on the map. + * Single parameters can be set if necessary. False means the value is locked, true means they can be modified. + * + * @public + * @param {object} [{ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false }={}] + * @memberof GeoMap + */ unlock({ rotatable = true, translatable = true, movableX = true, movableY = true, scalable = true } = {}) { - if (this.image && this.image.scatter) { - this.image.scatter.translatable = translatable; - this.image.scatter.movableX = movableX; - this.image.scatter.movableY = movableY; - this.image.scatter.rotatable = rotatable; - this.image.scatter.scalable = scalable; - } - // Issue #001 - // // Rotation does not yet work with the cover mechanism. - // //this.rotatable = true - // this.translatable = true - // this.scalable = true + this.lock({ rotatable, translatable, movableX, movableY, scalable }); } + /** + * Unloads the image of the map. + * + * @public + * @memberof GeoMap + */ unload() { if (this.image) { if (this.image.parent) { @@ -17822,6 +17840,12 @@ } } + /** + * Removes the map, freeing all memory ba flushing handlers and removing the image. + * + * @public + * @memberof GeoMap + */ remove() { if (this.image) this.image.mask = null; @@ -17855,8 +17879,6 @@ this.image = image; if (frame) this.setFrame(frame); - let boundaries = this.mapdata.getBoundaries(); - let scatterOpts = Object.assign({ cover: this.cover, scaleable: this.scaleable, @@ -17866,7 +17888,6 @@ startScale: this.startScale, minScale: this.minScale, maxScale: this.maxScale, - boundaries, onTransform: this.transformed.bind(this) }); @@ -17922,7 +17943,7 @@ * to a coordinate with latitude and longitude. * * - * @param {object} point - Point in form of {x: x_val, y: y_val}. + * @param {object} point - Point in form of {x, y}. * @returns {object} - Coordinates on the map in form of {x: latitude, y: longitude}. */ coordinatesFromPoint(point) { @@ -17934,7 +17955,7 @@ * Transform coordinates in the map into pixel positions on the deep zoom image. * * @param {object} coords - Coordinates of a map position in form {x: latitude, y: longitude}. - * @return - Returns a image position in form of {x: x_val, y: y_val}. + * @return {Point} - Returns a image position in form of {x: x, y: y}. */ coordinatesToPoint(coordinates) { return this.toAbsolutePixelCoordinates(this.mapdata.toPixel(coordinates)) @@ -19630,6 +19651,13 @@ } } + /** + * MapList is a list of maps with one active index. + * It contains some utility functions to change the map. + * + * @export + * @class MapList + */ class MapList { constructor(active = null, maps = {}) { this.maps = maps; @@ -19641,8 +19669,9 @@ /** * Selects a map from the map list. * + * @public * @param {string} active - Name of the map to select. - * @returns + * @returns {Map} - Returns the active map. Returns null if no map was added to the MapList. * @memberof MapList */ select(active) { @@ -19672,6 +19701,13 @@ return map } + /** + * Clones the entire maplist. + * + * @public + * @returns {MapList} - Returns a cloned instance of this map list. + * @memberof MapList + */ clone() { let maps = {}; @@ -19682,6 +19718,14 @@ return new MapList(this.active, maps) } + /** + * Adds a new map to the map list. + * + * @public + * @param {string} key - Key to identify the map. + * @param {GeoMap} map - The GeoMap to add. + * @memberof MapList + */ add(key, map) { if (this.maps[key] != null) consol.warn('Key already in mapList. The existing key was overwritten.'); if (this.active == null) this.active = key; @@ -19689,10 +19733,25 @@ this.maps[key] = map; } + /** + * Returns the the active map. + * If none is set, it returns null. + * + *@public + * @readonly + * @memberof MapList + */ get map() { return this.maps && this.maps[this.active] ? this.maps[this.active] : null } + /** + * Selects the next map in the map array. + * + * @public + * @returns {GeoMap} - Returns the next map in the list. + * @memberof MapList + */ next() { let keys = Object.keys(this.maps); let idx = keys.indexOf(this.active); @@ -19701,6 +19760,13 @@ return next } + /** + * Removes all maps from the maplist. + * And cleans up all maps. + * + * @public + * @memberof MapList + */ cleanup() { for (let key in this.maps) { let map = this.maps[key]; @@ -20283,9 +20349,9 @@ } selectMap(key) { + if (this.debug) console.log('Select map', key, result); let result = this.mapList.select(key); - console.log('Select map', key, result); if (result && this.mapLayer) { this.mapLayer.changeMap(this.mapList.map); } @@ -20318,6 +20384,14 @@ this.onTransform.call(this, event); } + /** + * + * Called when the mapLayer changed the map. + * + * @private + * @param {*} lastMap + * @memberof MapApp + */ _mapChanged(lastMap) { if (lastMap) { lastMap.flushHandlers(); @@ -20648,8 +20722,7 @@ * * @static * @export - * @class GeoJsonGraphics - * @extends {GeoGraphics} + * @class */ class GeoJson { static isLineType(type) { @@ -20701,7 +20774,6 @@ } list.push({ type, coordinates }); - // console.log({type, coordinates}) }); return list @@ -20765,7 +20837,7 @@ * considered valid. A complete list is provided in the GeoUtils. * * @param {object} point - The point that is tested for validity. - * @returns + * @returns {boolean} * @memberof GeoJson */ static validateAndConvertPoint(point) { @@ -20944,7 +21016,7 @@ * {latitude: lat, longitude: lng} * * @static - * @param {object / array} coordinate - Coordinate to be tested, if it is an valid coordinate. + * @param {object|array} coordinate - Coordinate to be tested, if it is an valid coordinate. * @returns - Returns the coordinate properly transformed. If transformation was not possible, it returns null. * @memberof GeoGraphics */ diff --git a/lib/doctest.js b/lib/doctest.js index 8ea7ddd..b15f783 100755 --- a/lib/doctest.js +++ b/lib/doctest.js @@ -145,43 +145,49 @@ export default class Doctest { let container = document.createElement('div') container.className = 'doctest-wrapper' - let titleParent = container - if (doctest.hasAttribute('data-collapsible')) { - let collapsibleToggle = document.createElement('div') + if (doctest.hasAttribute('data-title') || doctest.hasAttribute('data-collapsible')) { + let titlebar = document.createElement('div') + titlebar.className = 'doctest-titlebar' + titlebar.style = 'min-height: 10px;' + container.appendChild(titlebar) - let icon = document.createElement('i') - icon.className = 'material-icons' - collapsibleToggle.appendChild(icon) + if (doctest.hasAttribute('data-title')) { + let title = document.createElement('h6') + title.innerText = doctest.getAttribute('data-title') + title.className = 'doctest-section-title' + titlebar.appendChild(title) + } - collapsibleToggle.className = 'doctest-collapsible-toggle' - collapsibleToggle.style = 'min-height: 10px;' - titleParent = collapsibleToggle - container.appendChild(collapsibleToggle) + if (doctest.hasAttribute('data-collapsible')) { + let icon = document.createElement('i') + icon.className = 'material-icons' + titlebar.classList.add('doctest-collapsible-toggle') - const collapsedClass = 'collapsed' - - function setToggleMode(collapse) { - if (collapse) { - container.classList.add(collapsedClass) - icon.innerText = 'arrow_drop_down' + if (titlebar.childNodes.length > 0) { + titlebar.insertBefore(icon, titlebar.childNodes[0]) } else { - container.classList.remove(collapsedClass) - icon.innerText = 'arrow_drop_up' + titlebar.appendChild(icon) } - } - function determineToggleMode() { - setToggleMode(!container.classList.contains(collapsedClass)) - } + const collapsedClass = 'collapsed' - setToggleMode(doctest.hasAttribute('data-collapsed')) - collapsibleToggle.addEventListener('click', determineToggleMode) - } - if (doctest.hasAttribute('data-title')) { - let title = document.createElement('h6') - title.innerText = doctest.getAttribute('data-title') - title.className = 'doctest-section-title' - titleParent.appendChild(title) + function setToggleMode(collapse) { + if (collapse) { + container.classList.add(collapsedClass) + icon.innerText = 'arrow_drop_down' + } else { + container.classList.remove(collapsedClass) + icon.innerText = 'arrow_drop_up' + } + } + + function determineToggleMode() { + setToggleMode(!container.classList.contains(collapsedClass)) + } + + setToggleMode(doctest.hasAttribute('data-collapsed')) + titlebar.addEventListener('click', determineToggleMode) + } } let pre = document.createElement('pre') diff --git a/lib/pixi/bundle.js b/lib/pixi/bundle.js index 12b52c7..e4e05b2 100755 --- a/lib/pixi/bundle.js +++ b/lib/pixi/bundle.js @@ -62,7 +62,6 @@ window.FontInfo = FontInfo window.Text = Text //Maps -import MapView from './maps/mapview.js' import { GeoMap, ImageMap, DeepZoomMap } from './maps/map.js' import { MapData, DeepZoomMapData } from './maps/mapdata.js' @@ -80,7 +79,8 @@ window.Projection = { Robinson } -window.MapView = MapView +import MapViewport from './maps/mapviewport.js' +window.MapViewport = MapViewport import MapApp from './maps/mapapp.js' diff --git a/lib/pixi/index.html b/lib/pixi/index.html index bbce2ea..5b6cd78 100644 --- a/lib/pixi/index.html +++ b/lib/pixi/index.html @@ -37,6 +37,7 @@ const index = new Index(itemTemplate, [ ['Flippable', 'flippable.html'], ['LabeledGraphics', 'labeledgraphics.html'], ['List', 'list.html'], + ['Maps', 'maps/index.html'], ['Message', 'message.html'], ['Modal', 'modal.html'], ['Tooltip', 'tooltip.html'], diff --git a/lib/pixi/maps/geojson.js b/lib/pixi/maps/geojson.js index 4f6e919..83c4e22 100644 --- a/lib/pixi/maps/geojson.js +++ b/lib/pixi/maps/geojson.js @@ -6,8 +6,7 @@ import { GeoGraphics, GeoShape, GeoMultiShape, GeoLine, GeoPoint } from './geogr * * @static * @export - * @class GeoJsonGraphics - * @extends {GeoGraphics} + * @class */ export default class GeoJson { static isLineType(type) { @@ -59,7 +58,6 @@ export default class GeoJson { } list.push({ type, coordinates }) - // console.log({type, coordinates}) }) return list @@ -123,7 +121,7 @@ export default class GeoJson { * considered valid. A complete list is provided in the GeoUtils. * * @param {object} point - The point that is tested for validity. - * @returns + * @returns {boolean} * @memberof GeoJson */ static validateAndConvertPoint(point) { @@ -302,7 +300,7 @@ export class GeoUtils { * {latitude: lat, longitude: lng} * * @static - * @param {object / array} coordinate - Coordinate to be tested, if it is an valid coordinate. + * @param {object|array} coordinate - Coordinate to be tested, if it is an valid coordinate. * @returns - Returns the coordinate properly transformed. If transformation was not possible, it returns null. * @memberof GeoGraphics */ diff --git a/lib/pixi/maps/geolayer.js b/lib/pixi/maps/geolayer.js index 7e11823..e129151 100644 --- a/lib/pixi/maps/geolayer.js +++ b/lib/pixi/maps/geolayer.js @@ -1,9 +1,9 @@ import { GeoMap } from './map.js' -import MapView from './mapview.js' import { EventHandler } from './utils.js' import { GeoGraphics } from './geographics.js' import { MapList } from './maplist.js' -//import { GeoGraphics } from "../pixi/geographics.js" +import MapViewport from './mapviewport.js' +import { ScatterContainer } from '../scatter.js' /** * The GeoLayer is a special PIXILayer, that recognizes other GeoLayers and @@ -93,6 +93,13 @@ export class GeoLayer { return this._visibility } + /** + * Alias for geoLayer.displayObject.addChild. + * + * @public + * @param {GeoGraphics | PIXI.DisplayObject} element - Element to add to the displayObject. + * @memberof GeoLayer + */ addChild(element) { this.displayObject.addChild(element) } @@ -117,15 +124,6 @@ export class GeoLayer { } else console.error('There was no map specified.', this) } - // place(geographic) { - // if (geographic.constructor.name.startsWith('Geo') && geographic.graphics) { - // // Fix to remove the rollupjs circular dependency - // //if (geographic instanceof GeoGraphics) { - // this.geographics.push(geographic) - // super.place(geographic.graphics) - // } else super.place(geographic) - // } - removeFromParent() { if (this.parent) { this.parent.removeLayer(this) @@ -165,8 +163,15 @@ export class GeoLayer { return this._parent } + /** + * Adds a GeoLayer as child to the GeoLayer. + * + * @public + * @param {GeoLayer} layer - GeoLayer to add. + * @memberof GeoLayer + */ addLayer(layer) { - if (layer instanceof GeoLayer || layer instanceof MapLayer) { + if (layer instanceof GeoLayer) { layer.removeFromParent() this.layers.push(layer) @@ -218,6 +223,18 @@ export class GeoLayer { // } } +/** + * The map layer is responsible for showing certain maps, at a specific position It contains + * a list of available maps and can switch between them seamlessly. GeoGraphics placed on the MapLayer itself + * or child Geolayers will be adapted to maps and adjusted on map change automatically. + * + * The map layer is the 'king' of the geo layers. Every geolayer + * needs a map layer at it's root. Otherwise they won't work- + * + * @export + * @class MapLayer + * @extends {GeoLayer} + */ export class MapLayer extends GeoLayer { constructor( mapList, @@ -247,7 +264,7 @@ export class MapLayer extends GeoLayer { listeners: onChange }) - this.mapview = new MapView({ + this.mapview = new MapViewport({ zoom, focus, viewport @@ -279,22 +296,34 @@ export class MapLayer extends GeoLayer { this._mapChangeLocked = false } + /** + * Adapts all child layers and their GeoGraphics. + * + * This is called primarily on a map change. + * + * @private + * @memberof MapLayer + */ adapt() { this.layers.forEach(layer => { if (layer.adapt) layer.adapt(this.map) }) } - focus(coordinates, zoom) { - this.mapview.updateFocusPoint(this.map) - } - transformed(e) { this.mapview.transformed(this.map) this.layers.forEach(layer => layer.parentMapLayerTransformed(this)) this.transformHandler.call(this) } + /** + * Clones the map layer- + * + * @param {ScatterContainer} scatterContainer - ScatterContainer of the app. + * @param {PIXI.DisplayObject} [container=null] - Container of the newly created MapLayer. If null, an empty PIXI.Container will be created. + * @returns + * @memberof MapLayer + */ clone(scatterContainer, container = null) { let mapList = this.mapList.clone() container = container == null ? new PIXI.Container() : container @@ -369,23 +398,46 @@ export class MapLayer extends GeoLayer { } } + /** + * Applies the mapviews focus to the map. + * This may be useful, if the container was modified. + * + * @memberof MapLayer + */ refocus() { this.mapview.apply(this.map) } + /** + * @public + * @returns {GeoMap} - Returns the active map. + * @readonly + * @memberof MapLayer + */ get map() { return this.mapList.map } /** - * This is required for the consistency of georelated layers. - * The request traverses up to the mapLayer where it then returns - * the responsible map layer. + * + * This is required for the geo layers. + * MapLayer requests from the geoLayers traverse up to the next MapLayer. + * + * @public + * @returns {MapLayer} - Returns this MapLayer. + * @readonly + * @memberof MapLayer */ get mapLayer() { return this } + /** + * Cleans up the MapLayer. + * + * @public + * @memberof MapLayer + */ cleanup() { this.mapList.cleanup() } diff --git a/lib/pixi/maps/index.html b/lib/pixi/maps/index.html new file mode 100644 index 0000000..5e6e2b5 --- /dev/null +++ b/lib/pixi/maps/index.html @@ -0,0 +1,112 @@ + + + + PIXI Maps Doctests + + + + + + + + + + + + +
+ +

Maps Module

+

The maps module provides a handy toolkit to easily integrate maps in an application. Create a full screen map + application by using the mapapp. Utilize the GeoLayer-system to integrate maps in an existing application. + Draw graphics onto the map using geographical positions instead of pixel positions with the GeoGraphics. + Or just use an Overlay to quickly draw icons for each point on a map. +

+
+
+ +
+ + + + \ No newline at end of file diff --git a/lib/pixi/maps/map.js b/lib/pixi/maps/map.js index 5464fe7..c39ffb5 100644 --- a/lib/pixi/maps/map.js +++ b/lib/pixi/maps/map.js @@ -93,10 +93,18 @@ export class GeoMap { } flushHandlers() { - // this.onLoaded + this.onLoad.empty() this.onTransform.empty() } + /** + * Locks all transformations on the map. + * Single parameters can be set if necessary. False means the value is locked, true means they can be modified. + * + * @public + * @param {object} [{ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false }={}] + * @memberof GeoMap + */ lock({ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false } = {}) { if (this.image && this.image.scatter) { this.image.scatter.translatable = rotatable @@ -105,30 +113,26 @@ export class GeoMap { this.image.scatter.rotatable = movableY this.image.scatter.scalable = scalable } - - // Issue #001: This causes the map to not be displayed at the correct position on - // map change. - // // Rotation does not yet work with the cover mechanism. - // //this.rotatable = false - // this.translatable = false - // this.scalable = false } + /** + * Unlocks all transformations on the map. + * Single parameters can be set if necessary. False means the value is locked, true means they can be modified. + * + * @public + * @param {object} [{ rotatable = false, translatable = false, movableX = false, movableY = false, scalable = false }={}] + * @memberof GeoMap + */ unlock({ rotatable = true, translatable = true, movableX = true, movableY = true, scalable = true } = {}) { - if (this.image && this.image.scatter) { - this.image.scatter.translatable = translatable - this.image.scatter.movableX = movableX - this.image.scatter.movableY = movableY - this.image.scatter.rotatable = rotatable - this.image.scatter.scalable = scalable - } - // Issue #001 - // // Rotation does not yet work with the cover mechanism. - // //this.rotatable = true - // this.translatable = true - // this.scalable = true + this.lock({ rotatable, translatable, movableX, movableY, scalable }) } + /** + * Unloads the image of the map. + * + * @public + * @memberof GeoMap + */ unload() { if (this.image) { if (this.image.parent) { @@ -142,6 +146,12 @@ export class GeoMap { } } + /** + * Removes the map, freeing all memory ba flushing handlers and removing the image. + * + * @public + * @memberof GeoMap + */ remove() { if (this.image) this.image.mask = null @@ -175,8 +185,6 @@ export class GeoMap { this.image = image if (frame) this.setFrame(frame) - let boundaries = this.mapdata.getBoundaries() - let scatterOpts = Object.assign({ cover: this.cover, scaleable: this.scaleable, @@ -186,7 +194,6 @@ export class GeoMap { startScale: this.startScale, minScale: this.minScale, maxScale: this.maxScale, - boundaries, onTransform: this.transformed.bind(this) }) @@ -242,7 +249,7 @@ export class GeoMap { * to a coordinate with latitude and longitude. * * - * @param {object} point - Point in form of {x: x_val, y: y_val}. + * @param {object} point - Point in form of {x, y}. * @returns {object} - Coordinates on the map in form of {x: latitude, y: longitude}. */ coordinatesFromPoint(point) { @@ -254,7 +261,7 @@ export class GeoMap { * Transform coordinates in the map into pixel positions on the deep zoom image. * * @param {object} coords - Coordinates of a map position in form {x: latitude, y: longitude}. - * @return - Returns a image position in form of {x: x_val, y: y_val}. + * @return {Point} - Returns a image position in form of {x: x, y: y}. */ coordinatesToPoint(coordinates) { return this.toAbsolutePixelCoordinates(this.mapdata.toPixel(coordinates)) diff --git a/lib/pixi/maps/mapapp.js b/lib/pixi/maps/mapapp.js index e3b5544..7b37618 100644 --- a/lib/pixi/maps/mapapp.js +++ b/lib/pixi/maps/mapapp.js @@ -11,6 +11,9 @@ import { MapList } from './maplist.js' * MapApp is responsible for showing fullscreen * map applications. * + * @export + * @class MapApp + * @extends {PIXIApp} */ export default class MapApp extends PIXIApp { constructor(opts = {}) { @@ -191,9 +194,9 @@ export default class MapApp extends PIXIApp { } selectMap(key) { + if (this.debug) console.log('Select map', key, result) let result = this.mapList.select(key) - console.log('Select map', key, result) if (result && this.mapLayer) { this.mapLayer.changeMap(this.mapList.map) } @@ -226,6 +229,14 @@ export default class MapApp extends PIXIApp { this.onTransform.call(this, event) } + /** + * + * Called when the mapLayer changed the map. + * + * @private + * @param {*} lastMap + * @memberof MapApp + */ _mapChanged(lastMap) { if (lastMap) { lastMap.flushHandlers() diff --git a/lib/pixi/maps/mapdata.js b/lib/pixi/maps/mapdata.js index 95b8f7c..b93a87e 100644 --- a/lib/pixi/maps/mapdata.js +++ b/lib/pixi/maps/mapdata.js @@ -14,7 +14,7 @@ export class MapData { * @constructor * @param {Projection}[projection] - Specifies the projection of the map (e.g. Mercator Projection). * @param {object}[opts] - Addiditonal options. - * @param {[[minLat, minLng],[maxLat, maxLng]]}[opts.bounds] - Describes the minimum and maximum coordinates on the map + * @param {array}[opts.bounds] - Describes the minimum and maximum coordinates on the map in the form of {[[minLat, minLng],[maxLat, maxLng]]}. * @param {Point}[opts.translate] - Defines a translation, when clipping is not an option (e.g. when the whole world is shown, but translated.) */ constructor(projection, opts = {}) { @@ -52,6 +52,7 @@ export class MapData { /** * Transforms a pixel point on the map to a geographical coordinate. * + * @public * @param {{x,y} | PIXI.Point} point - A pixel position on the map. * @returns {{x,y} | PIXI.Point} - A geographical coordinate. * @memberof MapData @@ -84,6 +85,7 @@ export class MapData { /** * Transform a geographical coordinate to a pixel point on the map. * + * @public * @param {{x,y} | PIXI.Point} coordinates - A point in the form of {x:lat,y:lng}. * @returns {{x,y} | PIXI.Point} point - A pixel position on the map. * @memberof MapData @@ -116,6 +118,18 @@ export class MapData { return point } + + /** + * Get's the clipping of the map data. Clipping describes the + * piece of the map that is shown. E.g. if we just show a map of + * europe, then we have to set the clipping properly, otherwise + * the preojection would produce the wrong results when transforming + * from a point to coordinates or the other way around. + * + * @readonly + * @memberof MapData + * @returns {object} - Object that contains a min and max value of the clipping in form of: {min: {x,y}, max:{x,y}}. Where x and y are in between 0 and 1. + */ get clip() { let unclipped = { min: { x: 0, y: 0 }, @@ -125,30 +139,30 @@ export class MapData { return this.opts.clip ? this.opts.clip : unclipped } + /** - * Bounds to pixel transforms some bounds in form of {min:{x:minLat, y:minLng},max:{x:maxLat, y:maxLng}} - * to pixel coordinates. + * Returns the biggest viewport the mapdata allows. + * This is determined by the projecton or the clipping on the mapapp. * + * @readonly + * @memberof MapData */ - getBoundaries() { - // let min = this.toPixel(bounds.min) - // let max = this.toPixel(bounds.max) - - // Y values needs to be swapped, as PIXI has it's origin - // in the top-left corner and a regular map in the bottom-left corner. - let boundaries = { - min: { x: 0, y: 0 }, - max: { x: 1, y: 1 } - } - - return boundaries - } - get maxViewport() { return this.opts.clip ? this.opts.clip : this.projection.maxViewport } } + +/** + * Special mapdata for DeepZoomMap objects. + * + * Note: It just transform the clipping parameter of the tiles config + * to the clipping of the mapapp. + * + * @export + * @class DeepZoomMapData + * @extends {MapData} + */ export class DeepZoomMapData extends MapData { constructor(projection, tilesConfig, opts = {}) { if (tilesConfig.clip) { diff --git a/lib/pixi/maps/maplist.js b/lib/pixi/maps/maplist.js index fe1c1ee..08e77c8 100644 --- a/lib/pixi/maps/maplist.js +++ b/lib/pixi/maps/maplist.js @@ -1,3 +1,10 @@ +/** + * MapList is a list of maps with one active index. + * It contains some utility functions to change the map. + * + * @export + * @class MapList + */ export class MapList { constructor(active = null, maps = {}) { this.maps = maps @@ -9,8 +16,9 @@ export class MapList { /** * Selects a map from the map list. * + * @public * @param {string} active - Name of the map to select. - * @returns + * @returns {Map} - Returns the active map. Returns null if no map was added to the MapList. * @memberof MapList */ select(active) { @@ -40,6 +48,13 @@ export class MapList { return map } + /** + * Clones the entire maplist. + * + * @public + * @returns {MapList} - Returns a cloned instance of this map list. + * @memberof MapList + */ clone() { let maps = {} @@ -50,6 +65,14 @@ export class MapList { return new MapList(this.active, maps) } + /** + * Adds a new map to the map list. + * + * @public + * @param {string} key - Key to identify the map. + * @param {GeoMap} map - The GeoMap to add. + * @memberof MapList + */ add(key, map) { if (this.maps[key] != null) consol.warn('Key already in mapList. The existing key was overwritten.') if (this.active == null) this.active = key @@ -57,10 +80,25 @@ export class MapList { this.maps[key] = map } + /** + * Returns the the active map. + * If none is set, it returns null. + * + *@public + * @readonly + * @memberof MapList + */ get map() { return this.maps && this.maps[this.active] ? this.maps[this.active] : null } + /** + * Selects the next map in the map array. + * + * @public + * @returns {GeoMap} - Returns the next map in the list. + * @memberof MapList + */ next() { let keys = Object.keys(this.maps) let idx = keys.indexOf(this.active) @@ -69,6 +107,13 @@ export class MapList { return next } + /** + * Removes all maps from the maplist. + * And cleans up all maps. + * + * @public + * @memberof MapList + */ cleanup() { for (let key in this.maps) { let map = this.maps[key] diff --git a/lib/pixi/maps/mapviewport.html b/lib/pixi/maps/mapviewport.html new file mode 100644 index 0000000..a1249f2 --- /dev/null +++ b/lib/pixi/maps/mapviewport.html @@ -0,0 +1,163 @@ + + + + + + MapViewport + + + + + + + + + + + + + + + + +

MapViewport

+

+ The MapViewport works under the hood of a map layer to track the informations about the current focus point and + zoom position. + This is important to maintain the same view when maps are changed. +

+ +
+
+

WHAT TO SEE: The map should focus Paris.

+ + + + + \ No newline at end of file diff --git a/lib/pixi/maps/mapview.js b/lib/pixi/maps/mapviewport.js similarity index 99% rename from lib/pixi/maps/mapview.js rename to lib/pixi/maps/mapviewport.js index 3c28d0c..d4d82ff 100644 --- a/lib/pixi/maps/mapview.js +++ b/lib/pixi/maps/mapviewport.js @@ -6,7 +6,7 @@ import { DeepZoomMap } from './map.js' * It ensures, that maps can be changed, without the user noticing it. * */ -export default class MapView { +export default class MapViewport { /** * * @param {object} [focus = {x:0, y:0}] - Defines the startup focuspoint of the app. diff --git a/lib/thumbnail.png b/lib/thumbnail.png index 196e6eb..3dab009 100644 Binary files a/lib/thumbnail.png and b/lib/thumbnail.png differ