<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: bolo</title>
    <description>The latest articles on DEV Community by bolo (@bolollo).</description>
    <link>https://dev.to/bolollo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1212213%2Fc4873c5f-1307-47b5-9fe1-9a42c68074de.jpeg</url>
      <title>DEV Community: bolo</title>
      <link>https://dev.to/bolollo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bolollo"/>
    <language>en</language>
    <item>
      <title>MapTiler Server on Raspberry Pi - A Geeks' Guide to Self-Hosted Maps</title>
      <dc:creator>bolo</dc:creator>
      <pubDate>Tue, 23 Sep 2025 11:34:46 +0000</pubDate>
      <link>https://dev.to/bolollo/maptiler-server-on-raspberry-pi-a-geeks-guide-to-self-hosted-maps-19d4</link>
      <guid>https://dev.to/bolollo/maptiler-server-on-raspberry-pi-a-geeks-guide-to-self-hosted-maps-19d4</guid>
      <description>&lt;h2&gt;
  
  
  Unleash Your Inner Cartographer (and Powerful Maps!)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Build Your Own Map Server?
&lt;/h3&gt;

&lt;p&gt;Tired of relying on Google Maps? With &lt;strong&gt;MapTiler Server&lt;/strong&gt; on a Raspberry Pi, you’ll get:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Privacy and offline&lt;/strong&gt;: Maps stay on your device.&lt;br&gt;
✅ &lt;strong&gt;Control&lt;/strong&gt;: Add custom styles, overlays, or data.&lt;br&gt;
✅ &lt;strong&gt;Experience&lt;/strong&gt;: Master Linux, APIs, and geospatial tech with ease.&lt;br&gt;
✅ &lt;strong&gt;Fun&lt;/strong&gt;: Build a sample "Explore Zurich" dashboard with beautiful offline maps!&lt;/p&gt;
&lt;h3&gt;
  
  
  What You’ll Build
&lt;/h3&gt;

&lt;p&gt;By the end of this guide, your Raspberry Pi will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Serve maps&lt;/strong&gt; like a pro (even with a free tier license).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Run a demo dashboard app&lt;/strong&gt; on your display or a &lt;strong&gt;full-screen dashboard&lt;/strong&gt; directly on the Pi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Handle basic tasks&lt;/strong&gt; like configuring Pi, uploading sample data, and deploying a simple web app.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  What You’ll Need
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Why You Need It&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raspberry Pi (4/5)&lt;br&gt;Raspberry 3 A+ too … wait until the end&lt;/td&gt;
&lt;td&gt;The brain of your map server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MicroSD card (32GB+)&lt;/td&gt;
&lt;td&gt;Storage for your OS and maps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power supply&lt;/td&gt;
&lt;td&gt;Keep your Pi alive!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitor/keyboard/mouse&lt;/td&gt;
&lt;td&gt;For setup (you can unplug later)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0fdzlng6vhb679kbtle.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0fdzlng6vhb679kbtle.jpg" alt="Raspberry Pi board" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Flashing the OS – Breathing Life into Your Pi
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Install Raspberry Pi Imager
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download &lt;strong&gt;Raspberry Pi Imager&lt;/strong&gt; from the &lt;a href="https://www.raspberrypi.com/software/" rel="noopener noreferrer"&gt;official website&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install it on your computer (available for Windows, macOS, and Linux).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 2: Choose the OS
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;Pi version&lt;/strong&gt; based on your model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Choose OS&lt;/strong&gt; and pick &lt;em&gt;Raspberry Pi OS (64-bit)&lt;/em&gt; or another compatible image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select your MicroSD card under &lt;strong&gt;Choose Storage&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Step 3: Use Edit Settings for Pre-Configuration
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Configure the following settings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hostname&lt;/strong&gt;: Set a custom name (e.g., pi-maps).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username and Password&lt;/strong&gt;: Create a username you like and a secure password for the admin user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wi-Fi&lt;/strong&gt;: Enter your SSID and password to connect automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locale&lt;/strong&gt;: Set your language and country code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH (under Services)&lt;/strong&gt;: Enable SSH for remote access.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Save&lt;/strong&gt; to return to the main menu.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9q2kylq7eqyx1fozua2j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9q2kylq7eqyx1fozua2j.png" alt="Raspberry Pi OS customisation settings" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 4: Finish the SD card and boot your Pi
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Write&lt;/strong&gt;, confirm, and wait for the process to complete.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Insert the MicroSD card into your Raspberry Pi and power it on.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The pre-configured settings will automatically apply, saving you time during setup!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Installing MapTiler Server on a Raspberry Pi via CLI
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Step 1: Download and Install MapTiler Server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;strong&gt;ARM64 .deb package&lt;/strong&gt; for MapTiler Server from the official website.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transfer the file to your Raspberry Pi (if downloaded on another machine).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
You can drag and drop the installer on to your SD card after flashing it. The installer will be located in &lt;code&gt;/boot/firmware/&lt;/code&gt; path. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the terminal on your Raspberry Pi and run:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  sudo dpkg -i maptiler-server-4.6.1-linux-arm64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;(use correct installer filename and path like &lt;code&gt;/boot/firmware/maptiler-server-4.6.1-linux-arm64.deb&lt;/code&gt;)&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 2: Start the Server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Launch MapTiler Server with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;maptiler-server
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;&lt;p&gt;The server will start, and you can access it in your browser at:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;http://:3650/admin/&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v61lf9qws9ymyfkkl0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4v61lf9qws9ymyfkkl0q.png" alt="MapTiler server sign-in screen" width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;If you run the server without options, Server automatically generates the initial config and password. Keep it for login to Server Admin interface.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Tip&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Run &lt;code&gt;maptiler-server --help&lt;/code&gt; to explore more options like how to set password, home dir, and other options.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Step 3: Enable Auto-Start (Optional)
&lt;/h3&gt;

&lt;p&gt;To ensure MapTiler Server starts automatically on boot as a service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo maptiler-server-servicify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command starts a script that guides you through setting up MapTiler Server’s working directory (use absolute path), port, and administration password. Then it creates the &lt;code&gt;systemd&lt;/code&gt; service file and starts the service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Free Sample Data to MapTiler Server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Download the Free Sample Data
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Go to MapTiler Data and log in (you have an account created from server installer download).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on "&lt;strong&gt;MY DATA&lt;/strong&gt;" in the top right corner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to the &lt;strong&gt;Server&lt;/strong&gt; tab and download the free &lt;strong&gt;sample data package&lt;/strong&gt; (a ZIP file). This package includes map styles and data for the Zurich area.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Upload the Sample Data to MapTiler Server
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the MapTiler Server admin interface in your browser:&lt;br&gt;
&lt;strong&gt;http://:3650/admin/&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Log in with your admin credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the admin interface, click "&lt;strong&gt;New Map&lt;/strong&gt;" or drag and drop the downloaded ZIP file directly into the interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Wait for MapTiler Server to process and upload the sample data.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0vwf72olb40woz471cu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq0vwf72olb40woz471cu.png" alt="Download MapTiler sample data package progress" width="492" height="177"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 3: Explore the Sample Data
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once uploaded, navigate to the &lt;strong&gt;Tiles&lt;/strong&gt; tab to preview the raw OpenStreetMap dataset for Zurich.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Switch to the &lt;strong&gt;Maps&lt;/strong&gt; tab to view different map styles (e.g., Streets, Outdoor, Satellite Hybrid).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These styles are pre-configured and ready to use with the Zurich dataset.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhga9myqol3ouca80tzqp.png" alt="MapTiler Server satellite hybrid map" width="800" height="557"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 4: Test Your Setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open any map style in your browser by clicking on it in the &lt;strong&gt;Maps&lt;/strong&gt; tab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use zoom levels up to 14 for full details in Zurich or experiment with over-zooming for higher levels.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Warning&lt;/strong&gt; &lt;br&gt;
On low-memory or lightweight Pi versions (such as my Pi 3 A+), &lt;strong&gt;STOP here&lt;/strong&gt;. Running MapTiler Server and a browser on the same board is not a great idea. However, you can use these versions to serve tiles to a browser running on another device.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Create a Dashboard on Raspberry Pi
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;An auto-rotating map display for exploring Zurich using Raspberry Pi's power&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create the HTML File
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;On your Raspberry Pi, create a new file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano ~/explore-zurich.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Paste this complete code:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Explore Zurich&amp;lt;/title&amp;gt;
&amp;lt;script src="https://cdn.maptiler.com/maptiler-sdk-js/v3.0.1/maptiler-sdk.umd.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link href="https://cdn.maptiler.com/maptiler-sdk-js/v3.0.1/maptiler-sdk.css" rel="stylesheet" /&amp;gt;
&amp;lt;style&amp;gt;
    body { margin: 0; padding: 0; }
    #map { position: absolute; top: 0; bottom: 0; width: 100%; }
    .map-title { 
        position: absolute; 
        top: 10px; 
        left: 10px; 
        z-index: 1; 
        background: white; 
        padding: 5px 10px; 
        border-radius: 5px;
        font-family: Arial;
    }
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;div class="map-title" id="styleName"&amp;gt;Zurich Explorer 🗺️&amp;lt;/div&amp;gt;
&amp;lt;div id="map"&amp;gt;&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
    // Initialize with MapTiler SDK
    maptilersdk.config.apiKey = '';  // No API key needed for local server

    // Zurich bounding box coordinates
    const ZURICH_BBOX = {
        minLon: 8.4476, 
        maxLon: 8.5926,
        minLat: 47.3362,
        maxLat: 47.4145
    };

    // Available styles from your sample data
    const styles = [
        { id: "basic", name: "Basic Style" },
        { id: "outdoor", name: "Outdoor Style" },
        { id: "streets", name: "Streets Style" },
        { id: "satellite-hybrid", name: "Satellite Hybrid" }
    ];

    let currentStyleIndex = 0;

    // Initialize map with the first style
    const map = new maptilersdk.Map({
        container: 'map',
        style: `http://localhost:3650/api/maps/basic/style.json`,
        center: [8.5417, 47.3769], // Zurich center
        zoom: 12
    });

    // Random position generator within Zurich
    function getRandomZurichPosition() {
        const lon = ZURICH_BBOX.minLon + 
            Math.random() * (ZURICH_BBOX.maxLon - ZURICH_BBOX.minLon);

        const lat = ZURICH_BBOX.minLat + 
            Math.random() * (ZURICH_BBOX.maxLat - ZURICH_BBOX.minLat);

        return [lon, lat];
    }

    // Update map every minute
    function updateMap() {
        // Cycle through styles
        currentStyleIndex = (currentStyleIndex + 1) % styles.length;
        const style = styles[currentStyleIndex];

        map.setStyle(`http://localhost:3650/api/maps/${style.id}/style.json`);
        document.getElementById('styleName').textContent = style.name;

        // Fly to random position
        map.flyTo({
            center: getRandomZurichPosition(),
            zoom: 14 + Math.random() * 4, // Random zoom between 14-18
            duration: 3000
        });
    }

    // Initial update and set interval
    map.on('load', function() {
        updateMap();
        setInterval(updateMap, 10000);
    });
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 2: Access the Dashboard
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Open Chromium browser on your Pi:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chromium-browser ~/explore-zurich.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For kiosk mode (fullscreen):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chromium-browser --kiosk ~/explore-zurich.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What You'll See
&lt;/h3&gt;

&lt;p&gt;✅ Automatic style rotation every 10secs&lt;br&gt;
✅ Smooth transitions between random Zurich locations&lt;br&gt;
✅ Four different map perspectives from your sample data&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwwjfia4zhja1g240mad.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgwwjfia4zhja1g240mad.gif" alt="Pi 3 A+ serving tiles to map dashboard running from desktop" width="8" height="4"&gt;&lt;/a&gt;&lt;br&gt;Pi 3 A+ serving tiles to map dashboard running from desktop.
  &lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Raspberry Pi 3 A+ is fine for hosting and serving tiles (especially with disabled GUI), but can't be used to render a web map dashboard to a display at the same time. Use recent Pi version (4/5) to get smooth map experience, pick &amp;gt;8GB memory board for hi-resolution displays.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For some scenarios, get the Pi IP address and connect to the console via SSH.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For a fully offline solution, put MapTiler SDK JS and CSS directly on the Pi and refer locally &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Beyond the Basics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.maptiler.com/guides/self-hosting/map-server/how-to-add-and-host-data-in-maptiler-server/" rel="noopener noreferrer"&gt;Adding custom data&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/?q=globe" rel="noopener noreferrer"&gt;Try switching to 3D / Globe view&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/" rel="noopener noreferrer"&gt;More SDK features&lt;/a&gt; - e.g., store locations in your lobby&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a daily fact about the randomly selected location using a &lt;a href="https://docs.maptiler.com/cloud/api/geocoding/" rel="noopener noreferrer"&gt;geocoding API&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.maptiler.com/sdk-js/modules/weather/" rel="noopener noreferrer"&gt;Implement a simple weather overlay for the chosen location&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.raspberrypi.com/documentation/computers/configuration.html#browser-2" rel="noopener noreferrer"&gt;Configure your Pi to run Chromium&lt;/a&gt;. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>raspberrypi</category>
      <category>map</category>
      <category>programming</category>
      <category>maptiler</category>
    </item>
    <item>
      <title>From zero to web mapping hero in 60 days</title>
      <dc:creator>bolo</dc:creator>
      <pubDate>Thu, 03 Oct 2024 09:46:06 +0000</pubDate>
      <link>https://dev.to/bolollo/from-zero-to-web-mapping-hero-in-60-days-3e21</link>
      <guid>https://dev.to/bolollo/from-zero-to-web-mapping-hero-in-60-days-3e21</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3zzimn7gw3pmaqgp59o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk3zzimn7gw3pmaqgp59o.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Over the past two years, I’ve focused on creating the documentation for the MapTiler SDK, an open-source JavaScript library designed to extend the functionality of the MapLibre SDK and simplify its use. I aimed to create a comprehensive resource with practical examples for building web maps. &lt;/p&gt;

&lt;p&gt;This summer, I shared the documentation through a series of tutorials on social media under the #SummerOfMaps hashtag. Each week, I covered a new topic with seven examples.&lt;/p&gt;

&lt;p&gt;Following the series from start to finish provides a solid foundation for building web maps, even if you have no prior experience, so I have gathered them all here in one place for you to work through!&lt;/p&gt;

&lt;h2&gt;
  
  
  Warm-up: What are web maps and how do they work
&lt;/h2&gt;

&lt;p&gt;The week before the launch, I shared a few articles and videos created by my colleagues. These resources cover the theoretical foundations of web maps, explaining what they are, how they function, and the underlying mathematics that makes them work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqwppevor36d2cy1y181.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqwppevor36d2cy1y181.png" alt="Image description" width="500" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=_do0Mc5uYzs" rel="noopener noreferrer"&gt;Map tiles &amp;amp; pyramid: How web maps work | Web Mapping Basic #1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=ufygsABmg8E" rel="noopener noreferrer"&gt;Zoom levels &amp;amp; map scale | Web Mapping Basic #2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=Jz_s21I2M_E" rel="noopener noreferrer"&gt;Lat Long, meters, and pixels in web maps | Web Mapping Basic #3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=ljZOyxo7QDQ" rel="noopener noreferrer"&gt;Map Projections EPSG: 3857 &amp;amp; 4326 | Web Mapping Basics #4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.maptiler.com/news/2019/02/what-are-vector-tiles-and-why-you-should-care/" rel="noopener noreferrer"&gt;What are vector tiles and why you should care&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to add a map to the web; the basics
&lt;/h2&gt;

&lt;p&gt;In the first week, I covered the basics of adding a map to a webpage. The only prerequisites were a basic understanding of JavaScript and HTML—no prior experience with web maps or map libraries was necessary.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjstp03hgr5na2zm0dnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvjstp03hgr5na2zm0dnn.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/add-map/" rel="noopener noreferrer"&gt;Add a map to a webpage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/how-to-use/" rel="noopener noreferrer"&gt;How to use the MapTiler SDK JS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/change-map-styles/" rel="noopener noreferrer"&gt;Change map styles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/language-map/" rel="noopener noreferrer"&gt;How to change the default map labels language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/3d-map/" rel="noopener noreferrer"&gt;Display a 3D terrain map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/ip-center-map/" rel="noopener noreferrer"&gt;How to center map based on visitor’s location&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/cooperative-gestures/" rel="noopener noreferrer"&gt;Cooperative gestures&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Pinpoint locations with markers
&lt;/h2&gt;

&lt;p&gt;A common feature of web maps is the marker, which indicates the location of specific elements. It could be a basic pin, a custom icon, an image, or something that reveals additional data when clicked. Markers can also connect to external data sources to load information dynamically. Throughout the tutorials, you'll learn how to implement each of these options.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q6ogectb9jjf3oezp3q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2q6ogectb9jjf3oezp3q.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/default-marker/" rel="noopener noreferrer"&gt;Display simple marker on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/add-image/" rel="noopener noreferrer"&gt;Add an icon to the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/animate-marker/" rel="noopener noreferrer"&gt;Animate a marker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/custom-marker-icons/" rel="noopener noreferrer"&gt;Add custom icons with markers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/set-popup/" rel="noopener noreferrer"&gt;Attach a popup to a marker instance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/custom-points-icon-png/" rel="noopener noreferrer"&gt;How to add a custom icon (PNG) to a point layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/custom-points-icon-svg/" rel="noopener noreferrer"&gt;How to add a custom icon (SVG) to a point layer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Present data as points on a map
&lt;/h2&gt;

&lt;p&gt;Points in web maps are used to represent individual data elements. You'll learn how to display points on a map, apply styling based on their attributes, and group them into clusters for easier visualization of large datasets. Additionally, you’ll explore how to convert point data into heatmaps, making it easier to spot density patterns and trends at a glance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd5k5zgqsi8bab2p2nk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyd5k5zgqsi8bab2p2nk7.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geojson-point/" rel="noopener noreferrer"&gt;Show point data from GeoJSON on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/animate-point-along-route/" rel="noopener noreferrer"&gt;Animate a point along a route&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-point-minimal/" rel="noopener noreferrer"&gt;Point layer (point helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-point-property-style/" rel="noopener noreferrer"&gt;Point layer colored and sized according to a property (point helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-point-label/" rel="noopener noreferrer"&gt;Point layer labels (point helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-point-cluster/" rel="noopener noreferrer"&gt;Point layer cluster (point helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-heatmap-minimal/" rel="noopener noreferrer"&gt;Heatmap layer (heatmap helper)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add lines to your web map
&lt;/h2&gt;

&lt;p&gt;Lines are another key element for displaying geographic information. You’ll learn how to add basic lines from GeoJSON, apply gradients, create lines that indicate progress (e.g., tracking a moving object), explore different line types, and style them for better visualization.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e927fwr4r5c4vv8z12x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7e927fwr4r5c4vv8z12x.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geojson-line/" rel="noopener noreferrer"&gt;Show line data from GeoJSON on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/line-gradient/" rel="noopener noreferrer"&gt;Create a gradient line using an expression&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/data-driven-lines/" rel="noopener noreferrer"&gt;Style lines with a data-driven property&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/live-update-feature/" rel="noopener noreferrer"&gt;Update a feature in realtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-polyline-gpx/" rel="noopener noreferrer"&gt;Add a GPX Line layer (polyline helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-polyline-dash-array/" rel="noopener noreferrer"&gt;Line dash pattern symbol (polyline helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-polyline-blur/" rel="noopener noreferrer"&gt;Line outline glow blur symbol (polyline helper)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Add polygons to your web map
&lt;/h2&gt;

&lt;p&gt;Polygons are another common way to represent geospatial data, often used to show area boundaries or the density of features within a region. You’ll learn how to add basic polygons, fill them with patterns or color gradients based on data intensity, integrate pop-ups, and combine them with points and lines for complex visualizations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpjs6eauw0fwnzpfaiow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpjs6eauw0fwnzpfaiow.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geojson-polygon/" rel="noopener noreferrer"&gt;Show polygon data from GeoJSON on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geojson-multigeometry/" rel="noopener noreferrer"&gt;Show multiGeometry data from GeoJSON on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-polygon-pattern/" rel="noopener noreferrer"&gt;Polygon fill pattern (polygon helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/helper-polygon-ramped-style/" rel="noopener noreferrer"&gt;Polygon color ramp symbol (polygon helper)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/polygon-popup-on-click/" rel="noopener noreferrer"&gt;Show polygon information on click&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/hover-styles/" rel="noopener noreferrer"&gt;Create a hover effect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/visualize-population-density/" rel="noopener noreferrer"&gt;Visualize population density&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to adjust map controls
&lt;/h2&gt;

&lt;p&gt;To enhance usability, you'll want to provide your users with intuitive control options. You'll learn how to add basic controls like zoom buttons and tilt &amp;amp; shift controls, as well as more advanced features such as location tracking, a scale bar, a minimap, geocoding search, and even an AR button that allows users to view the map in augmented reality on compatible devices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1029yt5er380kdjmzvjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1029yt5er380kdjmzvjb.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/event-ready/" rel="noopener noreferrer"&gt;Ready event&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geolocate-control/" rel="noopener noreferrer"&gt;Geolocate control how to get the user’s location using the GPS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/control-scale/" rel="noopener noreferrer"&gt;Scale control display&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/control-minimap/" rel="noopener noreferrer"&gt;How to display a minimap or overview map control to aid the map navigation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geocoder-component/" rel="noopener noreferrer"&gt;Geocoding control how to search places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geocoding-filter-country/" rel="noopener noreferrer"&gt;Geocoding search results to specified country(ies)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/ar-control/" rel="noopener noreferrer"&gt;Getting started with AR maps: Display an AR control on your maps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Adding additional data sources to a web map
&lt;/h2&gt;

&lt;p&gt;Even though MapTiler provides various data sources, there may be times when you need to incorporate your own data. You'll learn how to add custom layers, including raster layers, hillshade, vector tiles, local GeoJSON files, and even video, giving you full control over the map's content.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f70bzg8v72hm0dm1dko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4f70bzg8v72hm0dm1dko.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/raster-layer/" rel="noopener noreferrer"&gt;Show raster image on the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/hillshade/" rel="noopener noreferrer"&gt;Add hillshading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/wms/" rel="noopener noreferrer"&gt;Add a WMS source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/vector-source/" rel="noopener noreferrer"&gt;Add a vector tile source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/local-geojson/" rel="noopener noreferrer"&gt;View local GeoJSON&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/geojson-layer-in-stack/" rel="noopener noreferrer"&gt;Add a new layer below labels&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/video-on-a-map/" rel="noopener noreferrer"&gt;Add a video&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Create a weather map
&lt;/h2&gt;

&lt;p&gt;While often viewed as niche, weather maps are surprisingly easy to integrate into your website and are worth experimenting with. In the examples, you’ll learn how to add layers for precipitation, radar data, pressure, temperature, and wind direction. We'll also dive into more advanced use cases where you can combine multiple layers to create richer visualizations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezkibhjg5z09dcxcvc24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezkibhjg5z09dcxcvc24.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-precipitation/" rel="noopener noreferrer"&gt;Weather precipitation layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-radar/" rel="noopener noreferrer"&gt;Weather radar layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-pressure/" rel="noopener noreferrer"&gt;Weather pressure layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-temperature/" rel="noopener noreferrer"&gt;Weather temperature layer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-wind-direction/" rel="noopener noreferrer"&gt;Weather wind show direction arrow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-custom-popup/" rel="noopener noreferrer"&gt;Weather custom popup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/weather-layer-switcher/" rel="noopener noreferrer"&gt;Weather layer switcher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Complex examples
&lt;/h2&gt;

&lt;p&gt;In the final week, I shifted focus to more complex examples, combining the concepts from earlier tutorials with new techniques. These examples demonstrated how to build tools that could function as a minimal viable product for your future applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1l9jcmbd0sej1m9ycjqt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1l9jcmbd0sej1m9ycjqt.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/elevation-profile-control-simple/" rel="noopener noreferrer"&gt;Elevation profile control&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/elevation-at/" rel="noopener noreferrer"&gt;How to get the elevation at a given position&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/interactive-choropleth/" rel="noopener noreferrer"&gt;Interactive choropleth map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/point-filtering/" rel="noopener noreferrer"&gt;Point filtering by property&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/list-of-places/" rel="noopener noreferrer"&gt;How to sync the map with a list of places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/pois-info/" rel="noopener noreferrer"&gt;Get POIs information on click&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.maptiler.com/sdk-js/examples/switch-from-mapbox/" rel="noopener noreferrer"&gt;How to migrate/switch from Mapbox to MapTiler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Do you still want more?
&lt;/h2&gt;

&lt;p&gt;You can find all posts about the #SummerOfMaps series on &lt;a href="https://x.com/hashtag/SummerOfMaps?src=hashtag_click" rel="noopener noreferrer"&gt;Twitter/X&lt;/a&gt;, &lt;a href="https://www.linkedin.com/feed/hashtag/?keywords=summerofmaps" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, and &lt;a href="https://www.facebook.com/hashtag/summerofmaps" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt;. Our &lt;a href="https://dev.tourl"&gt;documentation&lt;/a&gt; and &lt;a href="https://dev.tourl"&gt;API reference&lt;/a&gt; provide even more examples.&lt;/p&gt;

&lt;p&gt;If you prefer using &lt;a href="https://docs.maptiler.com/leaflet/" rel="noopener noreferrer"&gt;Leaflet&lt;/a&gt;, &lt;a href="https://docs.maptiler.com/openlayers/" rel="noopener noreferrer"&gt;OpenLayers&lt;/a&gt;, or &lt;a href="https://documentation.maptiler.com/hc/en-us#JSFrameworks" rel="noopener noreferrer"&gt;other map libraries&lt;/a&gt;, you’ll find examples for them in the documentation as well.&lt;/p&gt;

</description>
      <category>maps</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to use Vector Tiles in Leaflet</title>
      <dc:creator>bolo</dc:creator>
      <pubDate>Fri, 17 Nov 2023 16:39:00 +0000</pubDate>
      <link>https://dev.to/bolollo/how-to-use-vector-tiles-in-leaflet-216o</link>
      <guid>https://dev.to/bolollo/how-to-use-vector-tiles-in-leaflet-216o</guid>
      <description>&lt;p&gt;&lt;a href="https://buff.ly/3sv80Ax"&gt;Leaflet&lt;/a&gt; is a lightweight open-source library for creating online maps. It works efficiently across all major desktop and mobile platforms and can be extended with many plugins.&lt;/p&gt;

&lt;p&gt;Leaflet doesn’t support vector tiles by default, but you can use one of the available &lt;a href="https://buff.ly/46iY9M2"&gt;plugins to display them&lt;/a&gt;. We will use the &lt;a href="https://buff.ly/47xHsNC"&gt;Basemaps with Vector Tiles&lt;/a&gt; plugin in this example. You’ll need a MapTiler account to use the plugin, but these are free for non-commercial use and give you access to a lot of great map styles. &lt;a href="https://buff.ly/3SMcYUi"&gt;You can create a free account here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know the differences between Raster and Vector data and when you should use vector tiles, we’ve added a handy guide to the end of this tutorial: Vector vs. Raster tiles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a map and display it on a web page
&lt;/h2&gt;

&lt;p&gt;Simple web technologies like HTML, CSS, and JavaScript are required to add a map to our web page. We’ve included all the code you need to create the page below.&lt;/p&gt;

&lt;h3&gt;
  
  
  HTML Boilerplate
&lt;/h3&gt;

&lt;p&gt;Create a basic HTML file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;meta charset="UTF-8"&amp;gt;
  &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
  &amp;lt;title&amp;gt;Display a map&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    body {
      margin: 0;
      padding: 0;
    }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;script&amp;gt;

&amp;lt;/script&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Include the Leaflet JavaScript and CSS files in the &lt;code&gt;head&lt;/code&gt; of your HTML file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" /&amp;gt;
&amp;lt;script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Map container and create a Map object
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element with a certain id where you want your map to be.&lt;/p&gt;

&lt;p&gt;Add &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; tag to your page. This div will be the container where the map will be loaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;body&amp;gt;
  &amp;lt;div id="map"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The div must have a non-zero height.  Create a rule for the style of the map in the CSS of the page. In this example, we are going to make a full-screen map.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in your JavaScript, create a map object. We’ll initialize the map with the id of the container element created before i.e. “map” and set its view to our chosen geographical coordinates  [lat, lng] and a zoom level.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const map = L.map('map').setView([0, 0], 2);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add the Vector Tiles basemap
&lt;/h3&gt;

&lt;p&gt;Leaflet is a JavaScript map API that does not provide any data. Leaflet depends on third parties to provide the basemap. Generally, Leaflet is used with Raster Tiles basemaps like OpenStreetMap, Esri, Bing Maps, MapTiler, etc.&lt;/p&gt;

&lt;p&gt;As previously explained, using a vector basemap has multiple advantages over raster maps. That is why we are going to use the &lt;a href="https://buff.ly/49DDlBF"&gt;Basemaps with Vector Tiles plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Include the plugin JavaScript and CSS files in the &lt;code&gt;head&lt;/code&gt; of your HTML file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All leaflet plugin libraries must be loaded &lt;strong&gt;after&lt;/strong&gt; Leaflet JavaScript&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script src="https://cdn.maptiler.com/maptiler-sdk-js/v1.1.2/maptiler-sdk.umd.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link href="https://cdn.maptiler.com/maptiler-sdk-js/v1.1.2/maptiler-sdk.css" rel="stylesheet" /&amp;gt;
&amp;lt;script src="https://cdn.maptiler.com/leaflet-maptilersdk/v1.0.0/leaflet-maptilersdk.js"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the &lt;code&gt;L.maptilerLayer&lt;/code&gt; class to create a layer to load and display our map.  In your JS code, after the map object creation, write the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mtLayer = L.maptilerLayer({ apiKey: `YOUR_MAPTILER_API_KEY_HERE` }).addTo(map);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Replace YOUR_MAPTILER_API_KEY_HERE with your actual &lt;a href="https://buff.ly/46lpYTU"&gt;MapTiler API key&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using the &lt;code&gt;L.maptilerLayer&lt;/code&gt; you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All the power of &lt;a href="https://buff.ly/3R1FnUW"&gt;MapTiler SDK JS&lt;/a&gt; to use vector tile layers (for data overlays) in your applications without any kind of limitation (show millions of geometries, choropleth maps, etc.).&lt;/li&gt;
&lt;li&gt;Multi-lingual vector tiles basemaps for Leaflet using the MapTiler SDK.&lt;/li&gt;
&lt;li&gt;Use any of the many &lt;a href="https://buff.ly/3ulepi6"&gt;professional-looking basemaps&lt;/a&gt; created by MapTiler, or use a map with your own custom basemap.&lt;/li&gt;
&lt;li&gt;Easily change the language of your map without having to create a new basemap.&lt;/li&gt;
&lt;li&gt;Locate the user and center the map accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Complete Code and Result
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /&amp;gt;
    &amp;lt;title&amp;gt;Vector Tiles in Leaflet JS&amp;lt;/title&amp;gt;
    &amp;lt;link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /&amp;gt;
    &amp;lt;script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="https://cdn.maptiler.com/maptiler-sdk-js/v1.1.2/maptiler-sdk.umd.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;link href="https://cdn.maptiler.com/maptiler-sdk-js/v1.1.2/maptiler-sdk.css" rel="stylesheet" /&amp;gt;
    &amp;lt;script src="https://cdn.maptiler.com/leaflet-maptilersdk/v1.0.0/leaflet-maptilersdk.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;style&amp;gt;
      #map {position: absolute; top: 0; right: 0; bottom: 0; left: 0;}
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id="map"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;script&amp;gt;
      const map = L.map('map').setView([0, 0], 1);
      const mtLayer = L.maptilerLayer({ apiKey: 'YOUR_MAPTILER_API_KEY_HERE' }).addTo(map);
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extra features of using the Vector Tiles plugin
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Change the map language
&lt;/h3&gt;

&lt;p&gt;If nothing is specified by default, the plugin uses the language defined in the browser.  To change the map language, use the setLanguage function of the maptilerLayer layer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mtLayer.setLanguage(ja); //change the language to Japanese
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use the built-in basemap styles.
&lt;/h3&gt;

&lt;p&gt;The plugin comes with a list of &lt;a href="https://buff.ly/3ulepi6"&gt;built-in basemap styles&lt;/a&gt;. It shows the street map by default, but you can easily change the styles using the setStyle function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mtLayer.setStyle(L.MaptilerStyle.DATAVIZ.DARK); //change to dark style map for data visualization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the plugin &lt;a href="https://buff.ly/47gQgYN"&gt;API reference&lt;/a&gt; for all options and methods. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Using a vector basemap has advantages over traditional raster basemaps. You can easily replace your raster basemap with a vector one. The rest of your application and layers will continue to work normally. Just replace the L.TileLayer layer with the L.maptilerLayer.&lt;/p&gt;

&lt;p&gt;Example: replace the OpenStreetMap basemap (L.tileLayer)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; const rasterLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© OpenStreetMap contributors'
}).addTo(map);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with the  vector tiles basemap (L.maptilerLayer)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mtLayer = L.maptilerLayer({ apiKey: 'YOUR_MAPTILER_API_KEY_HERE' }).addTo(map);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Raster vs Vector Map Tiles: What Is the Difference Between the Two Data Types?
&lt;/h3&gt;

&lt;p&gt;Web maps based on raster tiles technology are older but still widely used approach by many.&lt;/p&gt;

&lt;p&gt;Raster map tiles are actually nothing else than raster images. Zoomable raster maps consist of many raster map tiles (in the .png or .jpg format) placed next to each other, ordered in a pyramid scheme.&lt;/p&gt;

&lt;p&gt;Vector tiles also deliver data divided into roughly squared tiles, but they were introduced later. However, these tiles do not consist of raster images; they are made of geometric features such as points, curves, or polygons. Vector tiles are rendered on the client’s side with a style. This is a small text file that defines how certain map elements look and how they are displayed (e.g., a road can be defined as a solid red line placed on top of all map elements).&lt;/p&gt;

&lt;p&gt;It is possible to mix raster with vector tiles and get the best out of both, e.g., a satellite map (raster tiles) with an overlay of streets and labels available in different languages (vector tiles).&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>webdev</category>
      <category>maps</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
