203 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			203 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!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> |