iwmlib/lib/pixi/maps/maps.html

414 lines
13 KiB
HTML

<!doctype html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Maps</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>
.inline-showcase {
display: flex
}
.map-example {
display: inline-block;
width: 256px;
margin: 5px;
}
</style>
</head>
<body onload='Doctest.run()'>
<h1>Maps</h1>
<p>Maps represent a geographical image in a PIXI.Application. Preferably in a MapApp to have more convenient methods
to
handle the maps.</p>
<h2>Cover Test</h2>
<p>Usually maps should cover the whole app, or a window inside the app. Therefore they support a cover option.
This option allows the
</p>
<canvas id="bigMap">
</canvas>
<script class="doctest" data-title="Cover Map" data-collapsible data-collapsed>
(function () {
// Configuration of the deepzoom map.
let osmConfig = {
"projection": "mercator",
"type": "deepzoom",
"tiles": {
"tileSize": 256,
"format": "png",
"overlap": 0,
"type": "map",
"height": 2048,
"width": 2048,
"path": "../assets/maps/osm",
"urlTileTemplate": "{path}/{level}/{row}/{column}.{format}"
}
}
// We may use a focuspoint. This is the point the app
// sets in center on startup.
const Berlin = { x: 52.514961, y: 13.401366 }
let zoom = 3
const app = new MapApp({
view: bigMap,
root: "../",
width: 512,
height: 512,
coordsLogging: true,
focus: Berlin,
zoom
})
let osmMapProjection = new DeepZoomMapProjection(new Projection.Mercator(), osmConfig.tiles, {
app: app
})
let deepZoomMap = new DeepZoomMap(osmMapProjection, Object.assign({}, osmConfig.tiles, { app: app }), { cover: true })
app.setMap("deepzoom", deepZoomMap)
app.setup().run()
return app
})()
</script>
<script>
const Berlin = { x: 52.514961, y: 13.401366 }
function createDeepZoomMap(view, opts, mapOptipns = {}) {
let osmConfig = {
"projection": "mercator",
"type": "deepzoom",
"tiles": {
"tileSize": 256,
"format": "png",
"overlap": 0,
"type": "map",
"height": 2048,
"width": 2048,
"path": "../assets/maps/osm",
"urlTileTemplate": "{path}/{level}/{row}/{column}.{format}"
}
}
opts = Object.assign({
root: "../",
width: 256,
height: 256,
coordsLogging: true,
focus: Berlin
}, opts, { view })
const app = new MapApp(opts)
let osmMapProjection = new DeepZoomMapProjection(new Projection.Mercator(), osmConfig.tiles, {
app: app
})
let deepZoomMap = new DeepZoomMap(osmMapProjection, Object.assign({}, osmConfig.tiles, { app: app }), Object.assign({ cover: false }, mapOptipns))
app.setMap("deepzoom", deepZoomMap)
app.setup().run()
return app
}
function drawLocations(locations, maplayer) {
let locationLayer = new GeoLayer(new PIXI.Container(), { name: "Location Overlay" })
for (key in locations) {
let position = new GeoPoint(locations[key], {
/**
* To style GeoGraphics, the fill has to be set in the
* onDraw callback.
*
* Note: GeoPoints are the only GeoGraphic with no
* initial geometry attached. These have to be drawn to
* the graphics object manually.
*/
onDraw: function () {
this.graphics.beginFill(0xFF0000)
this.graphics.drawCircle(0, 0, 5)
this.graphics.endFill()
}
})
locationLayer.addChild(position)
}
maplayer.addLayer(locationLayer)
}
</script>
<h2>Map Types</h2>
<div class="inline-showcase">
<div class="map-example">
<canvas id="imagemap_canvas"></canvas>
<h3>Image Map</h3>
<p>A map, that is represented by a single image.</p>
</div>
<div class="map-example">
<canvas id="dzi_canvas"></canvas>
<h3>Deep Zoom Map</h3>
<p>The map representation is a DeepZoomImage, that can be scaled much more deeply, without losing quality by
increasing
the amount of tiles, that represent the image.</p>
<p>
You should see a map of the world with a set of cities highlighted with dots. When pressing the button
all views should jump
to the same point.
</p>
</div>
</div>
<script class='doctest' data-collapsible="true" data-collapsed data-title="Image Map">
// Create app.
let imageApp = new MapApp({
view: imagemap_canvas,
focus: Berlin,
width: 256,
height: 256,
coordsLogging: true,
})
// Specify image path.
let europe = "../assets/maps/pixabay/europe.jpg"
// The sprites of the images need to be loaded before initialization by pixi.
// Therefore this loading step is required.
imageApp.loadSprites([
europe
], (sprites) => ready(sprites), { resolutionDependent: false })
// Called when all textures are loaded.
let ready = (sprites) => {
// Define the map projection for the map.
let europeData = new MapProjection(new Projection.Mercator(), {
clip: {
min: { x: 32.863294, y: -18.58 },
max: { x: 57.467973, y: 44.277158 }
}
})
// Create the map using the texture and the map projection.
// Optionally customize the map by supplying secific options.
let imageMap = new ImageMap(sprites.get(europe), europeData, {
cover: false
})
// Set the map inside the app.
imageApp.setMap("europe", imageMap)
}
// Setup and run the app.
imageApp.setup().run()
</script>
<script class='doctest' data-collapsible="true" data-collapsed data-title="Deepzoom Map">
(function () {
// Create or (more commonly) load the data file for the map.
let mapConfig = {
"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}"
}
}
// Create the app by providing the canvas element.
const app = new MapApp({
view: dzi_canvas,
root: "../",
width: 256,
height: 256,
coordsLogging: true,
focus: Berlin
})
// Create the deepzoomdata.
let osmMapProjection = new DeepZoomMapProjection(new Projection.Mercator(), mapConfig.tiles, {
app
})
// Create the app.
let deepZoomMap = new DeepZoomMap(osmMapProjection, Object.assign({}, mapConfig.tiles, { app }), { cover: false })
// Set the map in the app.
app.setMap("deepzoom", deepZoomMap)
// Setup and run the app.
app.setup().run()
})()
</script>
<h1>Movement</h1>
<p>
Its crucial to focus certain points in a map application. The following tests the behavioud of maps inside a
mapapp and maps
inside of windows.
</p>
</ul>
<h2>Map Frame</h2>
<p>
The map's frame specifies the stage of the map. When moving to the focus point normally, the map focuses in the
center, the
frame defines the new area, the map will be centered in. This is important when trying to mask a map.
</p>
<canvas id="canvasFrameTest"></canvas>
<div class="controls">
<button id="nextCapital">Next Capital</button>
<input type="number" name="0" id="animationTime" min="0" value="0.35">
<span id="msg"></span>
</div>
<script class="doctest">
(function () {
// Create the app.
let app = createDeepZoomMap(canvasFrameTest, {
width: 512
})
let capitals = {
abidjan: { x: 5.349470, y: -4.006472 },
berlin: { x: 52.525430, y: 13.385291 },
canberra: { x: -35.282025, y: 149.128648 },
capetown: { x: -33.925448, y: 18.416962 },
moscow: { x: 55.750892, y: 37.622799 },
washington: { x: 38.895650, y: -77.031407 },
rio: { x: -22.871400, y: -43.280490 },
tokio: { x: 35.696278, y: 139.731366 }
}
// For debugging purposes we draw a visual
// representation of the frame.
let frame = new PIXI.Graphics()
frame.beginFill(0xFFFFFF, 0.5)
const border = 4
frame.lineStyle(border, 0xff0000, 1)
frame.drawRect(border / 2, border / 2, app.width / 2, app.height / 2)
const focusWidth = 4
frame.endFill()
frame.drawCircle(app.width / 4 + border / 2, app.height / 4 + border / 2, 10)
// For demonstration the frame object is a scatter
// element.
new DisplayObjectScatter(frame, app.renderer)
frame.interactive = true
frame.scatter.position = { x: 50, y: 50 }
// We set the frame to the map.
// Note: when using multiple maps, you should update the
// frame on every mapCHange
app.mapLayer.map.setFrame(frame)
app.scene.addChild(frame)
drawLocations(capitals, app.mapLayer)
// Add change focus event.
let visiting = 0
nextCapital.addEventListener("click", () => {
let keys = Object.keys(capitals)
visiting = (++visiting) % keys.length
let key = keys[visiting]
app.map.moveTo(capitals[key], null, { animate: parseFloat(animationTime.value) })
msg.innerHTML = "Visiting " + key + "."
})
})()
</script>
<script>
// function point_ready(sprites) {
// let maps_0 = ["world", "world2"]
// let sprite = sprites.get(osmworld)
// let worldOSMMap = new ImageMap(sprite, worlOSMdData, {
// cover: false,
// onLoaded: () => {
// worldOSMMap.setFrame(frame)
// }
// })
// pointApp.setMap(maps_0[0], worldOSMMap)
// let world2Map = new ImageMap(sprites.get(world2), world2Data, {
// cover: false,
// startScale: 1,
// onLoaded: function () {
// this.setFrame(frame)
// }
// })
// pointApp.addMap(maps_0[1], world2Map)
// pointApp.pixiLayer.place(frame)
// placeCapitals(pointApp.mapLayer)
// let active_0 = 0
// swapBtn_0.addEventListener("click", () => {
// active_0++
// pointApp.selectMap(maps_0[active_0 % maps_0.length])
// })
// }
</script>
</body>
</html>