<!doctype html> <html lang='en'> <head> <meta charset='UTF-8'> <title>MapData</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; } .map-container { position: relative; display: inline-flex; } .map-marker { position: absolute; transform: translate(-50%, -75%) scale(0.5); } </style> </head> <body onload='Doctest.run()'> <h1>MapData</h1> <p>Mapdata calculates is responsible for transforming map coordinates to pixel coordinates and backwards.</p> <h2>Static Squared World Map</h2> <p>The most simple example is a squared world map, thats projected with mercator transformation. Ranging from Longitude -180 to 180 and Latitude from -90 to 90 (Exclusive, because mercator gets infinite at +/-90). </p> <p>Coordinates: <strong id="map_coords_0"></strong> </p> <div id="mapContainerGeneral" class="map-container"> <img src="../assets/maps/osm/0/0/0.png" id="map_image_0" alt="Image is missing." width="512"> </div> <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 } } const europeanCapitalCities = { berlin: { x: 52.505949, y: 13.379400 }, 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 } } //Helper function to print the coordinates to a dom element. function printCoordinates(element, mapdata, out_dom) { element.addEventListener("mousemove", (event) => { let coords = mapdata.toCoordinates({ x: event.offsetX / event.target.width, y: event.offsetY / event.target.height }) out_dom.innerHTML = "Lat: " + coords.x.toFixed(4) + " Lng: " + coords.y.toFixed(4) }) } function placeMarker(parent, position) { const markerIconPath = "../../../assets/icons/room.png" let marker = document.createElement("img") marker.src = markerIconPath marker.className = "map-marker" Object.assign(marker.style, { left: (position.x * 100) + "%", top: (position.y * 100) + "%" }) parent.appendChild(marker) console.log(marker) } </script> <script class="doctest"> // Instantiate our mapdata. let squared_world = new MapData(new Projection.Mercator()); // Define a position, we are interested in in {x: latitude, y: longitude} let iceland = { x: 64.514979, y: -19.020796 } // Gets the normalized positition of the coordinates let pos_0 = squared_world.toPixel(iceland) // Helper function to set the dom marker. placeMarker(mapContainerGeneral, pos_0) </script> <script> printCoordinates(map_image_0, squared_world, map_coords_0) </script> <h2 id="germany">Clipped Map</h2> <p>Often we don't use the whole map, or our map is a subsection of the world. MapData can clip those cases, using the a bounding box of min and max coordinates.</p> <p>Coordinates: <strong id="map_coords_1"></strong> </p> <div class="map-container" id="mapContainerClipped"> <img src="../assets/maps/pixabay/europe.jpg" id="map_image_1" alt="Image is missing." width="512"> </div> <script class="doctest"> //Same procedure as above, just add a clipping parameter to the MapData object. let europe = new MapData(new Projection.Mercator(), { clip: { min: { x: 32.863294, y: -18.58 }, max: { x: 57.467973, y: 44.277158 } } }) //Same as above for (let coordinates of Object.values(europeanCapitalCities)) { let pixelPosition = europe.toPixel(coordinates) placeMarker(mapContainerClipped, pixelPosition) } </script> <script> printCoordinates(map_image_1, germany, map_coords_1) </script> <h2>Translated Map</h2> <p>Maps can be also translated, if the whole world is shown and clipping is not an option.</p> <p>Coordinates: <strong id="map_coords_2"></strong> </p> <div id="map_image_2" class="map-container""> </div> <script class=" doctest"> const size = 256 // Fake offset by using the old mapdata. let translation = squared_world.toPixel({ x: 90-10, y: -140 }) console.log(translation) //This map is clipped at the bottom // And also translated in hoizontal direction. // The translate option corrects that. let translated_world = new MapData(new Projection.Mercator(), { translate: { x: -10, y: 40 }, }) console.log(translation) Object.assign(map_image_2.style, { width: size + "px", height: size + "px", backgroundImage: "url(../assets/maps/osm/0/0/0.png)", backgroundColor: "red", backgroundPosition: translation.x * size + "px " +translation.y * size + "px" }) //Same as above for (let coordinates of Object.values(capitals)) { let position = translated_world.toPixel(coordinates) placeMarker(map_image_2, position) } </script> <script> map_image_2.addEventListener("mousemove", (event) => { let map = map_image_2 console.log(event.offsetX / map.width) let coords = translated_world.toCoordinates({ x: event.offsetX / map.offsetWidth, y: event.offsetY / map.offsetHeight }) map_coords_2.innerHTML = "Lat: " + coords.x.toFixed(4) + " Lng: " + coords.y.toFixed(4) }) </script> </body> </html>