<!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.mapList.next() console.log(app.mapList) 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>