Renamed 'MapView' to 'MapViewport'. Added documentation to the maps module.
This commit is contained in:
parent
60e28f8fe5
commit
65fac2f406
6
.gitignore
vendored
6
.gitignore
vendored
@ -80,3 +80,9 @@ typings/
|
||||
*.code-workspace
|
||||
.history/
|
||||
.vscode/
|
||||
|
||||
|
||||
# ignore generated contents-
|
||||
/doc/out/*
|
||||
**/thumbnails
|
||||
**/thumbnail.png
|
BIN
assets/logos/iwm_logo_2015_twitter.png
Normal file
BIN
assets/logos/iwm_logo_2015_twitter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.0 KiB |
170
dist/iwmlib.pixi.js
vendored
170
dist/iwmlib.pixi.js
vendored
@ -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
|
||||
*/
|
||||
|
@ -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')
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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'],
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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()
|
||||
}
|
||||
|
112
lib/pixi/maps/index.html
Normal file
112
lib/pixi/maps/index.html
Normal file
@ -0,0 +1,112 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>PIXI Maps Doctests</title>
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
<link rel="stylesheet" href="../../../css/index.css">
|
||||
|
||||
<script src="../../../dist/iwmlib.js"></script>
|
||||
|
||||
<template id="itemTemplate">
|
||||
<a class="wrapper" href="">
|
||||
<div class="preview">
|
||||
<div class="thumbnail-container">
|
||||
<div class="thumbnail">
|
||||
<img class="icon" src="thumbnails/notfound.png">
|
||||
<!-- <iframe src="" frameborder="0"></iframe> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="title"></div>
|
||||
</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-size: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#logo {
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
}
|
||||
|
||||
#logo>img {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
header>h1 {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
word-spacing: 0.25em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
header>p {
|
||||
max-width: 720px;
|
||||
line-height: 1.5em;
|
||||
color: rgb(207, 207, 207);
|
||||
}
|
||||
|
||||
header {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
background-color: #4c4f4f;
|
||||
color: whitesmoke;
|
||||
|
||||
padding: 68px 50px 10px 150px;
|
||||
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.container {
|
||||
|
||||
justify-content: center;
|
||||
|
||||
flex: 1;
|
||||
height: auto;
|
||||
min-height: auto;
|
||||
width: auto;
|
||||
min-width: auto;
|
||||
|
||||
margin: 0 60px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<a id="logo" target="_blank" href="http://www.iwm-tuebingen.de">
|
||||
<img src="../../../assets/logos/iwm_logo_2015_twitter.png">
|
||||
</a>
|
||||
<h1>Maps Module</h1>
|
||||
<p>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.
|
||||
</p>
|
||||
</header>
|
||||
<div id="container" class="container">
|
||||
|
||||
</div>
|
||||
<script>
|
||||
const index = new Index(itemTemplate, [
|
||||
["GeoGraphics", "geographics.html"],
|
||||
["GeoJson", "geojson.html"],
|
||||
["GeoMap", "map.html"],
|
||||
["MapApp", "mapapp.html"],
|
||||
["MapData", "mapdata.html"],
|
||||
["MapViewport", "mapviewport.html"],
|
||||
["Overlay", "overlay.html"],
|
||||
["Scatter", "scatter.html"]
|
||||
],
|
||||
null)
|
||||
index.load()
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -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))
|
||||
|
@ -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()
|
||||
|
@ -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) {
|
||||
|
@ -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]
|
||||
|
163
lib/pixi/maps/mapviewport.html
Normal file
163
lib/pixi/maps/mapviewport.html
Normal file
@ -0,0 +1,163 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="dark-mode">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>MapViewport</title>
|
||||
|
||||
<script src="../../3rdparty/highlight/highlight.pack.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="../../../fonts/material-icon-font/material-icons.css">
|
||||
<link rel='stylesheet' href='../../3rdparty/highlight/styles/vs2015.css'>
|
||||
<link rel='stylesheet' href='../../../css/doctest.css'>
|
||||
|
||||
<script src="../../../dist/iwmlib.3rdparty.js"></script>
|
||||
<script src="../../../dist/iwmlib.js"></script>
|
||||
<script src="../../../dist/iwmlib.pixi.js"></script>
|
||||
|
||||
|
||||
<style>
|
||||
.controls {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body onload="Doctest.run()">
|
||||
<h1>MapViewport</h1>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<canvas id="canvas"></canvas>
|
||||
<div id="mapControl"></div>
|
||||
<div id="cityControl" class="controls"></div>
|
||||
<p><strong>WHAT TO SEE:</strong> The map should focus Paris.</p>
|
||||
<script>
|
||||
let osmConfig = {
|
||||
"projection": "mercator",
|
||||
"type": "deepzoom",
|
||||
"tiles": {
|
||||
"tileSize": 256,
|
||||
"format": "png",
|
||||
"overlap": 0,
|
||||
"type": "map",
|
||||
"height": 1024,
|
||||
"width": 1024,
|
||||
"path": "../assets/maps/osm",
|
||||
"urlTileTemplate": "{path}/{level}/{row}/{column}.{format}"
|
||||
}
|
||||
}
|
||||
|
||||
let testConfig = {
|
||||
"projection": "mercator",
|
||||
"type": "deepzoom",
|
||||
"tiles": {
|
||||
"tileSize": 128,
|
||||
"format": "jpg",
|
||||
"overlap": 0,
|
||||
"type": "map",
|
||||
"height": 4096,
|
||||
"width": 4096,
|
||||
"path": "../assets/maps/test",
|
||||
"urlTileTemplate": "{path}/{level}/{row}/{column}.{format}"
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<script class="doctest">
|
||||
let capitals = {
|
||||
london: { x: 51.5, y: -0.083333 },
|
||||
rome: { x: 41.9, y: 12.483333 },
|
||||
madrid: { x: 40.4, y: -3.683333 },
|
||||
paris: { x: 48.833986, y: 2.346989 }
|
||||
}
|
||||
|
||||
// You may define a focus point ...
|
||||
let focus = capitals.paris
|
||||
|
||||
// ... and a zoom level.
|
||||
let zoom = 1
|
||||
|
||||
// Name has to be app (like all other PIXIApps).
|
||||
const app = (window.app = new MapApp({
|
||||
focus,
|
||||
zoom,
|
||||
view: canvas,
|
||||
coordsLogging: true,
|
||||
width: 512,
|
||||
height: 512
|
||||
}))
|
||||
|
||||
// As map an image of europe is used.
|
||||
let europe = '../assets/maps/pixabay/europe.jpg'
|
||||
|
||||
//Preload all required sprites for the image map.
|
||||
app.loadSprites([europe], sprites => ready(sprites), {
|
||||
resolutionDependent: false
|
||||
})
|
||||
|
||||
// The mapdata object contains informations,
|
||||
// how the displayed map has to be interpreted.
|
||||
// e.g. which projection is used or how the
|
||||
// image is clipped.
|
||||
let europeData = new MapData(new Projection.Mercator(), {
|
||||
clip: {
|
||||
min: { x: 32.863294, y: -18.58 },
|
||||
max: { x: 57.467973, y: 44.277158 }
|
||||
}
|
||||
})
|
||||
|
||||
function ready(sprites) {
|
||||
|
||||
const cover = true
|
||||
|
||||
// When resources are loaded, the ImageMap can be instantiated.
|
||||
let imageMap = new ImageMap(sprites.get(europe), europeData, {
|
||||
coordsLogging: true,
|
||||
maxScale: 1,
|
||||
cover
|
||||
})
|
||||
|
||||
let testMapData = new DeepZoomMapData(new Projection.Mercator(), testConfig.tiles, {
|
||||
app
|
||||
})
|
||||
let testMap = new DeepZoomMap(testMapData, Object.assign({}, testConfig.tiles, { app }), { cover })
|
||||
app.addMap("test", testMap)
|
||||
|
||||
let osmMapData = new DeepZoomMapData(new Projection.Mercator(), osmConfig.tiles, {
|
||||
app
|
||||
})
|
||||
let deepZoomMap = new DeepZoomMap(osmMapData, Object.assign({}, osmConfig.tiles, { app }), { cover })
|
||||
app.addMap("osm", deepZoomMap)
|
||||
|
||||
// Finally apply the map to the MapApp
|
||||
app.setMap('europe', imageMap)
|
||||
|
||||
// The app requires a map before beeing able to run.
|
||||
// So start the app here.
|
||||
app.setup().run()
|
||||
|
||||
for (let [key, val] of Object.entries(app.mapList.maps)) {
|
||||
let mapBtn = document.createElement("button")
|
||||
mapBtn.innerText = key
|
||||
mapBtn.addEventListener("click", () => {
|
||||
app.mapLayer.changeMap(val)
|
||||
})
|
||||
mapControl.appendChild(mapBtn)
|
||||
}
|
||||
}
|
||||
|
||||
for (let [key, val] of Object.entries(capitals)) {
|
||||
let cityBtn = document.createElement("button")
|
||||
cityBtn.innerText = key
|
||||
cityBtn.addEventListener("click", () => {
|
||||
app.mapLayer.map.moveTo(val)
|
||||
})
|
||||
cityControl.appendChild(cityBtn)
|
||||
}
|
||||
</script>
|
||||