Continued refactoring of the maps library.
This commit is contained in:
parent
58cbd44a7b
commit
285e41434a
@ -5,7 +5,10 @@
|
||||
<meta charset='UTF-8'>
|
||||
<title>GeoGraphics</title>
|
||||
|
||||
<link rel='stylesheet' href='../../3rdparty/highlight/styles/default.css'>
|
||||
<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>
|
||||
@ -67,11 +70,11 @@
|
||||
wikimedia
|
||||
], (sprites) => {
|
||||
|
||||
let osmMap = new ImageMap(sprites.get(osmworld), new MapData(new Projection.Mercator()), { cover: false })
|
||||
let osmMap = new ImageMap(sprites.get(osmworld), new MapData(new Projection.Mercator()), { cover: true })
|
||||
|
||||
let wikimediaMap = new ImageMap(sprites.get(wikimedia), new MapData(new Projection.Robinson(10)), {
|
||||
baseZoomHeight: sprites.get(osmworld).texture.height,
|
||||
cover: false
|
||||
cover: true
|
||||
})
|
||||
|
||||
app.addMaps({
|
||||
@ -89,7 +92,6 @@
|
||||
function enableSwitch(button, app) {
|
||||
button.addEventListener("click", () => {
|
||||
let next = app.mapList.next()
|
||||
console.log(app.mapList)
|
||||
app.selectMap(next)
|
||||
})
|
||||
}
|
||||
|
@ -127,6 +127,14 @@ export class GeoGraphics {
|
||||
return this._position
|
||||
}
|
||||
|
||||
get layer() {
|
||||
return this._layer ? this._layer : null
|
||||
}
|
||||
|
||||
setLayer(layer) {
|
||||
this._layer = layer
|
||||
}
|
||||
|
||||
// get map() {
|
||||
// if (
|
||||
// this.graphics.layer &&
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { GeoMap } from './map.js'
|
||||
import MapView from './mapview.js'
|
||||
import { EventHandler } from './utils.js'
|
||||
|
||||
import { PIXILayer } from '../../../../src/layers/js/layer.js'
|
||||
import Logging from '../../logging.js'
|
||||
import { GeoGraphics } from './geographics.js'
|
||||
import { MapList } from './maplist.js'
|
||||
//import { GeoGraphics } from "../pixi/geographics.js"
|
||||
|
||||
/**
|
||||
@ -13,7 +11,7 @@ import { GeoGraphics } from './geographics.js'
|
||||
* of the Adaption.
|
||||
*/
|
||||
export class GeoLayer {
|
||||
constructor(displayObject) {
|
||||
constructor(displayObject, opts = {}) {
|
||||
if (displayObject == null || !(displayObject instanceof PIXI.DisplayObject)) {
|
||||
console.error(
|
||||
`You need to provide a displayObject to make a ${this.constructor.name} out of it.`,
|
||||
@ -22,15 +20,14 @@ export class GeoLayer {
|
||||
return null
|
||||
} else {
|
||||
this.geographics = []
|
||||
displayObject.map = this
|
||||
// displayObject.map = this
|
||||
this.displayObject = displayObject
|
||||
|
||||
this.layers = []
|
||||
|
||||
this.pixiAddChild = displayObject.addChild.bind(displayObject)
|
||||
displayObject.addChild = (...elements) => {
|
||||
elements.forEach(element => {
|
||||
if (element instanceof GeoGraphics) {
|
||||
element.setLayer(this)
|
||||
this.geographics.push(element)
|
||||
this.pixiAddChild(element.graphics)
|
||||
} else {
|
||||
@ -39,6 +36,62 @@ export class GeoLayer {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
this.name = opts['name'] != null ? opts.name : 'Unnamed Layer'
|
||||
this.parent = null
|
||||
this.parentMapLayerTransformedHandler = new EventHandler('onParentMapLayerTransformed')
|
||||
this.layers = []
|
||||
this._visibility = { min: 0, max: Number.MAX_VALUE }
|
||||
}
|
||||
|
||||
parentMapLayerTransformed(mapLayer) {
|
||||
this.layers.forEach(layer => {
|
||||
if (!(layer instanceof MapList)) {
|
||||
layer.parentMapLayerTransformed()
|
||||
}
|
||||
})
|
||||
|
||||
this.parentMapLayerTransformedHandler.call(null, mapLayer)
|
||||
|
||||
this.rescaleChildren()
|
||||
}
|
||||
|
||||
rescaleChildren() {
|
||||
let map = this.map
|
||||
|
||||
if (this.rescale) {
|
||||
if (map != null) {
|
||||
let scale = map.image.scatter.scale
|
||||
|
||||
this.displayObject.children.forEach(graphics => {
|
||||
graphics.scale.set(1 / scale, 1 / scale)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let mapLayer = this.mapLayer
|
||||
if (this.visibility && mapLayer != null) {
|
||||
const zoom = mapLayer.mapview.zoom
|
||||
|
||||
// TODO
|
||||
// Currently I dont know what elemnts was.
|
||||
// We just log an error and resolve this on a later point.
|
||||
if (zoom > this.visibility.min && zoom < this.visibility.max) {
|
||||
this.displayObject.children.forEach(it => (it.visible = true))
|
||||
} else {
|
||||
this.displayObject.children.forEach(it => (it.visible = false))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set visibility(value) {
|
||||
let { min = 0, max = Infinity } = value
|
||||
console.log(min)
|
||||
this._visibility = { min, max }
|
||||
}
|
||||
|
||||
get visibility() {
|
||||
return this._visibility
|
||||
}
|
||||
|
||||
addChild(element) {
|
||||
@ -60,6 +113,8 @@ export class GeoLayer {
|
||||
this.layers.forEach(layer => {
|
||||
if (layer.adapt) layer.adapt(map)
|
||||
})
|
||||
|
||||
this.rescaleChildren()
|
||||
} else console.error('There was no map specified.', this)
|
||||
}
|
||||
|
||||
@ -72,19 +127,54 @@ export class GeoLayer {
|
||||
// } else super.place(geographic)
|
||||
// }
|
||||
|
||||
removeFromParent() {
|
||||
if (this.parent) {
|
||||
this.parent.removeLayer(this)
|
||||
}
|
||||
}
|
||||
|
||||
removeLayer(layer) {
|
||||
let idx = this.layers.indexOf(layer)
|
||||
if (idx != -1) {
|
||||
layer.parent = null
|
||||
this.layers.splice(idx, 1)
|
||||
|
||||
if (layer.displayObject.parent) {
|
||||
layer.displayObject.parent.removeChild(layer.displayObject)
|
||||
}
|
||||
} else console.warn('Tried to remove layer that was not set.', this, layer)
|
||||
}
|
||||
|
||||
set parent(parent) {
|
||||
this._parent = parent
|
||||
}
|
||||
|
||||
get parent() {
|
||||
return this._parent
|
||||
}
|
||||
|
||||
addLayer(layer) {
|
||||
if (layer instanceof GeoLayer || layer instanceof MapLayer) {
|
||||
layer.removeFromParent()
|
||||
|
||||
this.layers.push(layer)
|
||||
layer.parent = this
|
||||
layer.parentChanged()
|
||||
|
||||
this.displayObject.addChild(layer.displayObject)
|
||||
if (this.map) layer.geographics.forEach(geographics => geographics.adaptTo(this.map))
|
||||
} else
|
||||
console.error('Could not place layer. Only MapLayer and GeoLayers can be child layers of GeoLayers.', layer)
|
||||
}
|
||||
|
||||
parentChanged() {
|
||||
this.rescaleChildren()
|
||||
}
|
||||
|
||||
//GeoLayers have to be children of a map layer,
|
||||
// therefore we can recursively get the map.
|
||||
get map() {
|
||||
return this._mapLayer.map
|
||||
return this.mapLayer ? this.mapLayer.map : null
|
||||
}
|
||||
|
||||
get mapLayer() {
|
||||
@ -120,18 +210,12 @@ export class MapLayer extends GeoLayer {
|
||||
constructor(
|
||||
scatterContainer,
|
||||
displayObject,
|
||||
{ onTransform = null, onChange = null, focus = null, zoom = null, viewport = null } = {}
|
||||
{ onTransform = null, onChange = null, focus = null, zoom = null, viewport = null, mapList = null } = {}
|
||||
) {
|
||||
super(displayObject)
|
||||
|
||||
let onTransformListeners = [
|
||||
() => {
|
||||
this.labelVisibility()
|
||||
}
|
||||
]
|
||||
if (onTransform) onTransformListeners.push(onTransform)
|
||||
this.transformHandler = new EventHandler('onTransform', {
|
||||
listeners: onTransformListeners
|
||||
listeners: onTransform
|
||||
})
|
||||
|
||||
this.scatterContainer = scatterContainer
|
||||
@ -146,6 +230,7 @@ export class MapLayer extends GeoLayer {
|
||||
viewport
|
||||
})
|
||||
|
||||
this.mapList = mapList
|
||||
this._map = null
|
||||
|
||||
// //TODO Implement error handling here.
|
||||
@ -154,46 +239,6 @@ export class MapLayer extends GeoLayer {
|
||||
this.dynamicElements = new Map()
|
||||
}
|
||||
|
||||
labelVisibility() {
|
||||
const visibility = this.childrenVisibility
|
||||
|
||||
if (visibility) {
|
||||
const zoom = this.mapview.zoom
|
||||
|
||||
const min = visibility.min || 0
|
||||
const max = visibility.max || Number.MAX_VALUE
|
||||
|
||||
// TODO
|
||||
// Currently I dont know what elemnts was.
|
||||
// We just log an error and resolve this on a later point.
|
||||
if (this.elements) {
|
||||
if (zoom > min && zoom < max) {
|
||||
this.elements.forEach(it => (it.visible = true))
|
||||
|
||||
this.elements.forEach(it => {
|
||||
const scale = 1 / it.parent.scale.x
|
||||
|
||||
// it.children are poi groups
|
||||
// it.children[0] is the poi group of the tübingen poi
|
||||
// it.children[0].children are the text containers (not PIXI.Text), about 20 pieces
|
||||
|
||||
if (it.children.length > 0) {
|
||||
it.children[0].children.forEach(poi => {
|
||||
if (poi.children.length === 1) {
|
||||
poi.scale.set(scale, scale)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.elements.forEach(it => (it.visible = false))
|
||||
}
|
||||
}else{
|
||||
console.error("DEBUG: Elements was not defined.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
adapt() {
|
||||
this.layers.forEach(layer => {
|
||||
if (layer.adapt) layer.adapt(this.map)
|
||||
@ -209,6 +254,7 @@ export class MapLayer extends GeoLayer {
|
||||
|
||||
transformed(e) {
|
||||
this.mapview.transformed(this.map)
|
||||
this.layers.forEach(layer => layer.parentMapLayerTransformed(this))
|
||||
this.transformHandler.call(this)
|
||||
}
|
||||
|
||||
@ -243,8 +289,7 @@ export class MapLayer extends GeoLayer {
|
||||
useScatterAsContainer = true // If set to false, the normal container is used. This is necessary when using submaps and the container need to be a RigidContainer.*/
|
||||
) {
|
||||
if (map instanceof GeoMap) {
|
||||
|
||||
console.log("Change map to: " , map)
|
||||
console.log('Change map to: ', map)
|
||||
let oldMap = this.map
|
||||
if (oldMap) oldMap.unload()
|
||||
|
||||
@ -252,10 +297,9 @@ export class MapLayer extends GeoLayer {
|
||||
|
||||
this.map.load()
|
||||
this.scatterContainer.addChild(this.map.image)
|
||||
console.log(this.map.image.parent)
|
||||
|
||||
this.mapview.apply(this.map)
|
||||
map.image.addChild(this.displayObject)
|
||||
this.mapview.update(this.map)
|
||||
|
||||
// A geolayer's displayObject is on the parent layer.
|
||||
// A maplayer's displayobject is always the child of the map.
|
||||
|
@ -110,23 +110,26 @@
|
||||
})
|
||||
|
||||
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: false
|
||||
cover
|
||||
})
|
||||
|
||||
let testMapData = new DeepZoomMapData(new Projection.Mercator(), testConfig.tiles, {
|
||||
app
|
||||
})
|
||||
let testMap = new DeepZoomMap(testMapData, Object.assign({}, testConfig.tiles, { app }), { cover: false })
|
||||
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: false })
|
||||
let deepZoomMap = new DeepZoomMap(osmMapData, Object.assign({}, osmConfig.tiles, { app }), { cover })
|
||||
app.addMap("osm", deepZoomMap)
|
||||
|
||||
// Finally apply the map to the MapApp
|
||||
|
@ -105,7 +105,7 @@ export default class MapApp extends PIXIApp {
|
||||
super.setup()
|
||||
|
||||
// TODO get access to fps display
|
||||
let fpsDisplay
|
||||
let fpsDisplay = null
|
||||
this.stage.children.forEach(element => {
|
||||
if (element.refreshFps) fpsDisplay = element
|
||||
})
|
||||
@ -114,8 +114,7 @@ export default class MapApp extends PIXIApp {
|
||||
|
||||
this.ui = new PIXI.Container()
|
||||
this.scene.addChild(this.ui)
|
||||
|
||||
if (this.fpsLogging && fpsDisplay) this.ui.addChild(fpsDisplay)
|
||||
if (this.fpsLogging != null && fpsDisplay != null) this.ui.addChild(fpsDisplay)
|
||||
|
||||
if (this.coordsLogging) {
|
||||
this.coordsDisplay = new CoordinateDisplay(this)
|
||||
@ -216,11 +215,12 @@ export default class MapApp extends PIXIApp {
|
||||
lastMap.flushHandlers()
|
||||
}
|
||||
|
||||
this.map.onTransform.add(this.transformed.bind(this))
|
||||
|
||||
this.transformed()
|
||||
this.onMapChanged.call(this, this.map)
|
||||
|
||||
this.map.onTransform.add(this.transformed.bind(this))
|
||||
|
||||
|
||||
if (this.ui && this.ui.parent) {
|
||||
const parent = this.ui.parent
|
||||
parent.removeChild(this.ui)
|
||||
@ -249,11 +249,6 @@ export default class MapApp extends PIXIApp {
|
||||
this.overlayElements.set(layer, obj)
|
||||
}
|
||||
|
||||
|
||||
addMapOverlay(layer) {
|
||||
this.mapLayer.place(layer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the current coordinates to the clipboard.
|
||||
*/
|
||||
|
@ -27,7 +27,7 @@ export default class MapView {
|
||||
return this._zoom
|
||||
}
|
||||
|
||||
update(map) {
|
||||
apply(map) {
|
||||
map.moveTo(this._focus, this._zoom)
|
||||
}
|
||||
|
||||
@ -36,7 +36,7 @@ export default class MapView {
|
||||
this.updateFocusPoint(map)
|
||||
}
|
||||
|
||||
applyCameraPosition(map) {
|
||||
updatePosition(map) {
|
||||
this.updateFocusPoint(map)
|
||||
this.updateZoom(map)
|
||||
}
|
||||
@ -58,24 +58,39 @@ export default class MapView {
|
||||
}
|
||||
|
||||
mapPointToWindowPoint(map, point) {
|
||||
let windowPoint = { x: 0, y: 0 }
|
||||
|
||||
if (map['image'] && map.image['parent']) {
|
||||
let container = map.image.parent
|
||||
|
||||
let _point = new PIXI.Point(
|
||||
windowPoint = new PIXI.Point(
|
||||
map.scatter.position.x + map.scatter.scale * point.x,
|
||||
map.scatter.position.y + map.scatter.scale * point.y
|
||||
)
|
||||
|
||||
return container.toGlobal(_point)
|
||||
windowPoint = container.toGlobal(windowPoint)
|
||||
} else {
|
||||
console.error(this._noParentError)
|
||||
}
|
||||
|
||||
return windowPoint
|
||||
}
|
||||
|
||||
windowPointToMapPoint(map, point) {
|
||||
let pointOnMap = { x: 0, y: 0 }
|
||||
if (map['image'] && map.image['parent']) {
|
||||
let offset = map.image.parent.toGlobal({ x: 0, y: 0 })
|
||||
let _point = new PIXI.Point(
|
||||
pointOnMap = new PIXI.Point(
|
||||
(point.x - map.scatter.position.x - offset.x) / map.scatter.scale,
|
||||
(point.y - map.scatter.position.y - offset.y) / map.scatter.scale
|
||||
)
|
||||
} else console.error(this._noParentError)
|
||||
|
||||
return _point
|
||||
return pointOnMap
|
||||
}
|
||||
|
||||
get _noParentError() {
|
||||
return 'Cannot compute map point when map has no parent.'
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,6 +78,7 @@ export default class Overlay {
|
||||
scale: 1,
|
||||
rescale: false,
|
||||
popoverOffset: { x: 0, y: 0 },
|
||||
zoomVisibility: { min: 0, max: Number.MAX_VALUE },
|
||||
|
||||
/**
|
||||
* The following Attributes are taken from the TextStyle class
|
||||
@ -187,6 +188,10 @@ export default class Overlay {
|
||||
} = {}) {
|
||||
const name = this.name[0].toUpperCase() + this.name.slice(1).toLowerCase() + ' Overlay'
|
||||
let geoLayer = new GeoLayer(new PIXI.Container(), { name })
|
||||
|
||||
console.log(this)
|
||||
geoLayer.visibility = this.zoomVisibility
|
||||
|
||||
if (this.rescale) geoLayer.rescale = this.rescale
|
||||
this.items.forEach(item => {
|
||||
if (!excludeItems(item)) {
|
||||
@ -201,7 +206,6 @@ export default class Overlay {
|
||||
})
|
||||
return geoLayer
|
||||
}
|
||||
|
||||
getItemProperty(item, property) {
|
||||
let propertyValue = null
|
||||
const propertyExistsOnItem = item[property] !== undefined
|
||||
@ -508,7 +512,6 @@ export default class Overlay {
|
||||
maxWidth: 350
|
||||
})
|
||||
|
||||
|
||||
if (geographics.map) {
|
||||
const scale = 1 / geographics.map.scatter.scale
|
||||
popup.scale.set(scale, scale)
|
||||
|
@ -243,7 +243,7 @@
|
||||
let calculatedCoordinates = mercatorProjection.backward(relativePosition)
|
||||
|
||||
// Testcases for the backwards transformation.
|
||||
Doctest.expect(coordinates, calculatedCoordinates)
|
||||
Doctest.expectPointPrecision(coordinates, calculatedCoordinates)
|
||||
|
||||
let point = createPointAtPoisition(relativePosition)
|
||||
mercatorMap.appendChild(point)
|
||||
@ -317,7 +317,7 @@
|
||||
let relativePosition = robinsonProjection.forward(position)
|
||||
|
||||
// Run Test Cases
|
||||
Doctest.expect(robinsonTruth[key], relativePosition)
|
||||
Doctest.expectPointPrecision(robinsonTruth[key], relativePosition,0)
|
||||
|
||||
let point = createPointAtPoisition(relativePosition)
|
||||
robinsonMap.appendChild(point)
|
||||
|
@ -89,7 +89,7 @@ export class AdvancedScatterContainer extends ScatterContainer {
|
||||
let interactionManager = this.renderer.plugins.interaction
|
||||
|
||||
let displayObject = interactionManager.hitTest(local, this)
|
||||
console.log(displayObject.dontBlockScatter, displayObject.parent)
|
||||
|
||||
if (displayObject.dontBlockScatter && displayObject.parent != null) {
|
||||
displayObject = interactionManager.hitTest(local, displayObject.parent)
|
||||
}
|
||||
@ -97,7 +97,7 @@ export class AdvancedScatterContainer extends ScatterContainer {
|
||||
if (displayObject != null && displayObject.scatter != null) this.hitScatter = displayObject.scatter
|
||||
if (this.claimEvents) event.claimedByScatter = this.hitScatter
|
||||
|
||||
console.log(displayObject)
|
||||
|
||||
return this.hitScatter
|
||||
}
|
||||
}
|
||||
@ -331,26 +331,22 @@ export class CoverScatter extends AdvancedScatter {
|
||||
this.debugGraphics.endFill()
|
||||
}
|
||||
|
||||
if (this.cover) {
|
||||
// The reference to the element handler needs to be stored,
|
||||
// that we can remove it later on.
|
||||
const eventHandler = this._applyInitialCover.bind(this, null, true)
|
||||
this._applyInitialCover(eventHandler)
|
||||
}
|
||||
// if (this.cover) {
|
||||
// // The reference to the element handler needs to be stored,
|
||||
// // that we can remove it later on.
|
||||
// this._applyInitialCover = this._applyInitialCover.bind(this)
|
||||
// }
|
||||
}
|
||||
|
||||
_applyInitialCover(eventHandler, removeListener = false) {
|
||||
if (this.debug) console.log('ApplyInitialCover: ', parent)
|
||||
if (removeListener) {
|
||||
this.displayObject.off('added', eventHandler)
|
||||
}
|
||||
// _applyInitialCover() {
|
||||
// if (this.debug) console.log('ApplyInitialCover: ', parent)
|
||||
|
||||
if (this.displayObject.parent)
|
||||
this.forceCover(this.displayObject.parent.width, this.displayObject.parent.height)
|
||||
else {
|
||||
this.displayObject.on('added', eventHandler)
|
||||
}
|
||||
}
|
||||
// if (this.displayObject.parent)
|
||||
// this.forceCover(this.displayObject.parent.width, this.displayObject.parent.height)
|
||||
// else {
|
||||
// this.displayObject.on('added', eventHandler)
|
||||
// }
|
||||
// }
|
||||
|
||||
get boundaries() {
|
||||
if (this._boundaries) return this._boundaries
|
||||
@ -472,7 +468,11 @@ export class CoverScatter extends AdvancedScatter {
|
||||
if (this.scalable && this.parent != null) {
|
||||
if (this.cover) {
|
||||
let minCoverScale = this.calculateMinCoverScale(this.parent.width, this.parent.height)
|
||||
scale = scale < minCoverScale ? minCoverScale : scale
|
||||
if (scale < minCoverScale) {
|
||||
console.error('USE MIN COVER SCALE', minCoverScale, scale)
|
||||
|
||||
scale = minCoverScale
|
||||
}
|
||||
}
|
||||
this.scale = scale
|
||||
}
|
||||
@ -528,7 +528,6 @@ export class MapObjectScatter extends CoverScatter {
|
||||
)
|
||||
super(displayObject, renderer, opts)
|
||||
|
||||
|
||||
if (!renderer) {
|
||||
console.error('Renderer was not set!')
|
||||
return
|
||||
|
@ -331,8 +331,14 @@ export class EventHandler {
|
||||
}
|
||||
|
||||
call(context, ...args) {
|
||||
if (context == null) {
|
||||
this.listeners.forEach(listener => listener(...args))
|
||||
this.onces.forEach(listener => listener(...args))
|
||||
} else {
|
||||
this.listeners.forEach(listener => listener.call(context, ...args))
|
||||
this.onces.forEach(listener => listener.call(context, ...args))
|
||||
}
|
||||
|
||||
this.onces = []
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user