iwmlib/lib/pixi/maps/geographics.html

295 lines
9.9 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>GeoGraphics</title>
<link rel='stylesheet' href='../../3rdparty/highlight/styles/default.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>
<script>
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 }
}
window.apps = [
]
function createApp(view) {
let app = new MapApp({
view,
focus: { x: 0, y: 0 },
zoom: 1,
width: 512,
height: 512,
coordsLogging: true
})
const osmworld = "../assets/maps/osm/0/0/0.png"
const wikimedia = "../assets/maps/wikimedia-world-robinson/2000px-BlankMap-World.png"
return new Promise((resolve, reject) => {
setTimeout(() => {
reject("Creating app timed out.")
}, 3000)
app.loadSprites([
osmworld,
wikimedia
], (sprites) => {
let osmMap = new ImageMap(sprites.get(osmworld), new MapData(new Projection.Mercator()), { cover: false })
let wikimediaMap = new ImageMap(sprites.get(wikimedia), new MapData(new Projection.Robinson(10)), {
baseZoomHeight: sprites.get(osmworld).texture.height,
cover: false
})
app.addMaps({
"osm": osmMap, "wiki": wikimediaMap
})
app.selectMap("osm")
app.setup().run()
window.apps.push(app)
resolve(app)
}, { resolutionDependent: false })
})
}
function enableSwitch(button, app) {
button.addEventListener("click", () => {
let next = (app.activeMapKey == "osm") ? "wiki" : "osm"
console.log("CLICKED")
app.selectMap(next)
})
}
</script>
<body onload='Doctest.run()'>
<h1>GeoGraphics</h1>
<p> GeoGraphics are graphical objects, that does not store the graphics information
in screen space, but in geographical coordinates. Therefore GeoGraphics must be
placed on GeoLayers to work properly. </p>
<p><i>
Note: As GeoLayers are always children of a map layer. When the map is changed
all GeoLayers are notified via the 'adaptTo(map)' method.</i></p>
<p>
The geolayers forward this 'adaptTo' to all children that are GeoGraphics.
Which adjust their so called 'point' data to the new map.</p>
</ul>
<nav>
<ul>
<li><a href="#geopoint">Gep Point</a></li>
<li><a href="#geoline">Geo Line</a></li>
<li><a href="#geoshape">Geo Shape</a></li>
</ul>
</nav>
<!--GeoPoint -->
<section id="geopoint">
<h2>GeoPoint</h2>
<p>GeoPoint is a single coordinate in the map.</p>
<canvas id="geopoint_canvas"></canvas>
<div class=" controls">
<button id="geopoint_switch">Change Map</button>
</div>
<script class="doctest">
; (function () {
createApp(geopoint_canvas).then(app => {
let capitalContainer = new PIXI.Container()
let capitalLayer = new GeoLayer(capitalContainer)
for (key in capitals) {
let capitalPoint = new GeoPoint(capitals[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()
}
})
capitalContainer.addChild(capitalPoint)
}
enableSwitch(geopoint_switch, app)
// app.mapLayer.place(capitalLayer)
app.mapLayer.addLayer(capitalLayer)
}).catch(console.error)
})()
</script>
</section>
<!-- <section id="geoline">
<h2>GeoLine</h2>
<p>Geo line is a set of points, that are rendered as a line and can be updated individually.</p>
<canvas id="geoline_canvas"></canvas>
<div class="controls">
<button id="geoline_switch">Change Map</button>
<label>closed
<input type="checkbox" id="geoline_close_toggle">
</label>
</div>
<script class="doctest">
; (function () {
createApp(geoline_canvas).then(app => {
let overlay = new GeoLayer()
//// You can initialize the GeoLine with a set of coordinates.
let newYorkRooseveltAirField = { x: 40.738473, y: -73.613131 }
let aeroport_de_Paris_le_bourget = { x: 48.960373, y: 2.436891 }
// Instantiate the geo line.
let lindberghTransatlanticFlight = new GeoLine([
newYorkRooseveltAirField,
aeroport_de_Paris_le_bourget
], {
// Define how the line should be drawn.
// Note: This is called everytime the GeoGraphic
// has to adapt.
onDraw: function () {
this.graphics.lineStyle(3, 0xf8baea)
}
})
// Just place it on a GeoLayer.
overlay.place(lindberghTransatlanticFlight)
// Another option is to add points with the *addPoint()* method.
// This is useful for dynamic lines.
let geoline = new GeoLine([], {
onDraw: function () {
this.graphics.lineStyle(3, 0x00cc54, 0.5)
}
})
overlay.place(geoline)
for (let [name, coordinates] of Object.entries(capitals)) {
geoline.addPoint(coordinates)
}
// Don't forget to add the geolayer to the maplayer.
app.mapLayer.place(overlay)
enableSwitch(geoline_switch, app)
geoline_close_toggle.addEventListener("input", () => {
geoline.closed = geoline_close_toggle.checked
})
}).catch(console.error)
})()
</script>
</section>
<section id="geoshape">
<h2>Geoshape</h2>
<p>GeoGraphics represent Polygons, that are drawn on a map. If the map change, the graphic adapts to the new map
and represents
the same geographical shape.</p>
<div class="inline-showcase">
<div class="map-example">
<canvas id="geoshape_canvas"></canvas>
</div>
</div>
<button id="geoshape_switch">Change Map</button>
<script class='doctest'>
(function () {
createApp(geoshape_canvas).then((app) => {
let triangle = [
[capitals.berlin,
capitals.moscow,
capitals.tokio,
capitals.canberra,
capitals.capetown]
]
let countryLayer = new GeoLayer({ name: "Country Layer" })
let shape = new GeoShape(triangle, {
onDraw: function () {
this.graphics.beginFill(0xFF0000)
}
})
/**
* The following click handler should trigger when either the
* shape or a hole is clicked. This is the default and intended
* behaviour, as holes are considered to be contained by the
* desired geometry and should not interefere with any userinteraction.
*/
shape.graphics.interactive = true
shape.graphics.on("pointerdown", () => {
app.showNotification("Shape was clicked!")
})
countryLayer.place(shape)
app.mapLayer.place(countryLayer)
enableSwitch(geoshape_switch, app)
}).catch(console.error)
})()
</script>
</section>-->
</body>
</html>