Skip to content

βœ… Final Template Code for Lab 3

index.html
<!DOCTYPE html>
<html>
    <head>
        <title>Hello World with MapLibreGl</title>
        <!-- hint: remember to change your page title! -->
        <meta charset="utf-8" />
        <link rel="shortcut icon" href="#">
        <link rel="stylesheet" href="styles/style.css">

        <!-- MapLibreGL's css-->
        <link rel="stylesheet" href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" />

        <!-- MapLibreGL's JavaScript-->
        <script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
    </head>

    <body>
        <header>
            Hello World
            <!-- hint: you can make a menu with other links here if you'd like -->
        </header>

        <main>
            <div class="portfolio">
                <div id="contents"></div>
                <!-- Portfolio content goes here -->
                 <h2>Where I work</h2>
                 <ul>
                     <li>Los Angeles Metro</li>
                     <li>UCLA</li>
                     <li>Yindee Games</li>
                 </ul>
            </div>
            <div id="map"></div>
        </main>
        <div id="footer">
            Copyright(2024)
        </div>
        <script src="js/init.js"></script>
    </body>
</html>
styles/style.css
/* Global reset to ensure consistency across browsers */
* {
    font-family: Arial, sans-serif; /* Sets a default font for the whole page */
    margin: 0; /* Removes default margins */
    padding: 0; /* Removes default padding */
    box-sizing: border-box; /* Makes sure borders and paddings are included in the element's total width and height */
}

/* Sets the background color of the whole page and ensures content fits the screen height */
html {
    background-color: aqua; /* Sets a light blue background color */
}

/* Applies to both <html> and <body> */
html, body {
    height: 80vh; /* Sets the height to 80% of the viewport height, making sure the content fits on the screen */
    padding: 1rem; /* Adds a bit of space around the content for better readability */
    box-sizing: border-box; /* Ensures padding does not add to the set height */
}

/* Defines the main layout of the page using CSS Grid */
body {
    display: grid; /* Enables CSS Grid layout */
    grid-template-areas: 
        "header" /* Top area for the header */
        "main"   /* Middle area for the main content */
        "footer"; /* Bottom area for the footer */
    grid-template-rows: auto 1fr auto; /* Sizes: auto for header and footer to fit content, 1fr for main to fill remaining space */
}

/* Sets up the layout for the main content area, dividing it into two columns */
main {
    display: grid; /* Enables CSS Grid within the main element */
    grid-template-areas:
        "portfolio map"; /* Divides the main area into portfolio and map sections side by side */
    grid-template-columns: 1fr 1fr; /* Allocates equal width to both sections */
    grid-area: main; /* Assigns the main area to its grid area */
}

/* Grid area assignments for each major section, linking them to their respective areas in the grid */
header { 
    grid-area: header; /* Assigns the header to its grid area */
}

.portfolio {
    grid-area: portfolio;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

#map { 
    grid-area: map; /* Assigns the map section to its grid area */
    height: 80vh; /* Sets the map's height to 80% of the viewport height */
}

#footer {
    grid-area: footer;
    padding: 5px; /* Adds padding for better spacing */
    background-color: #4677a0; /* Sets a dark background for contrast */
    color: #fff; /* Ensures text is readable against the dark background */
    text-align: center; /* Centers the footer content */
}

#contents{
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
}
js/init.js
// declare variables
let mapOptions = {'centerLngLat': [-118.444,34.0709],'startingZoomLevel':5}

const map = new maplibregl.Map({
    container: 'map', // container ID
    style: 'https://api.maptiler.com/maps/streets-v2-light/style.json?key=wsyYBQjqRwKnNsZrtci1', // Your style URL
    center: mapOptions.centerLngLat, // Starting position [lng, lat]
    zoom: mapOptions.startingZoomLevel // Starting zoom level
});

function addMarker(lat,lng,title,message){
    let popup_message = `<h2>${title}</h2> <h3>${message}</h3>`
    new maplibregl.Marker()
        .setLngLat([lng, lat])
        .setPopup(new maplibregl.Popup()
            .setHTML(popup_message))
        .addTo(map)
    createButtons(lat,lng,title);
    return message
}

function createButtons(lat,lng,title){
    const newButton = document.createElement("button");
    newButton.id = "button"+title;
    newButton.innerHTML = title;
    newButton.setAttribute("lat",lat);
    newButton.setAttribute("lng",lng);
    newButton.addEventListener('click', function(){
        map.flyTo({
            center: [lng,lat],
        })
    })
    document.getElementById("contents").appendChild(newButton);
}

// When the map is fully loaded, start adding GeoJSON data
map.on('load', function() {
    fetch("map.geojson")
        .then(response => response.json())
        .then(data => {
            processData(data); // Call processData with the fetched data
        });
});

function processData(results){
    //console.log(results) //for debugging: this can help us see if the results are what we want
    results.features.forEach(feature => {
        //console.log(feature) // for debugging: are we seeing each feature correctly?
        // assumes your geojson has a "title" and "message" attribute
        let coordinates = feature.geometry.coordinates;
        let longitude = coordinates[0];
        let latitude = coordinates[1];
        let title = feature.properties.title;
        let message = feature.properties.message;
        addMarker(latitude,longitude,title,message);
    });
};

You can use this template to finish this week’s lab assignment!