Creates an animated map to fly between different locations

Using SDK JS, this example showcases the ability to navigate between various locations and present the distribution of schools in the United States through a heatmap layer at lower zoom levels. Additionally, a circle layer with a data-driven style is employed to provide more detailed information on school frequencies as the zoom level increases.

NPM module setup


npm install --save @maptiler/sdk
import { Map, MapStyle, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';

let lastLocationIndex = 0;

const locations = {
  usa: {zoom: 3.9, center: [-97.04, 38.17]},
  nyc: {zoom: 11.37, center: [-73.9757, 40.7684]},
  boston: {zoom: 11.82, center: [-71.07515, 42.37131]},
  chicago: {zoom: 11.48, center: [-87.6922, 41.8699]},
  houston: {zoom: 11.15, center: [-95.3843, 29.75]},
  sfBay: {zoom: 10.3, center: [-122.3634, 37.6689]},
  seattle: {zoom: 10.62, center: [-122.3241, 47.6127]},
}

const locationSequences = [
  locations.nyc,
  locations.boston,
  locations.chicago,
  locations.usa,
  locations.seattle,
  locations.sfBay,
  locations.houston,
  locations.usa,
]

config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';

const map = new Map({
  container: 'map',
  zoom: locationSequences[0].zoom,
  center: locationSequences[0].center,
  style: MapStyle.DATAVIZ.DARK, //learn more about map styles: https://docs.maptiler.com/sdk-js/api/map-styles/
  geolocateControl: false, //learn more about controls: https://docs.maptiler.com/sdk-js/api/controls/
  hash: true //add zoom, center latitude, center longitude, bearing, and pitch as hash fragment to URL
});

function sleepAsync(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function flyToAsync(map, options) {
  return new Promise(function(myResolve, myReject) {
    map.once("moveend", () => {
      myResolve(true);
    });

    map.once("touchstart", () => {
      myResolve(false);
    });

    map.once("mousedown", () => {
      myResolve(false);
    });

    map.flyTo(options);
  });
}

async function animateMap() {
  if (!map) return;

  let counter = 0;

  while(true) {
    lastLocationIndex = (lastLocationIndex + counter) % locationSequences.length;
    const reachedEnd = await flyToAsync(map, {
      ...locationSequences[lastLocationIndex],
      speed: 0.7,
    });
    await sleepAsync(850);
    
    counter ++;
  }
}

//add custom data and call animateMap() function
map.on('load', async () => {
  // add a clustered GeoJSON source for a sample set of earthquakes
  map.addSource('school_source', {
    'type': 'geojson',
    'data': 'https://docs.maptiler.com/sdk-js/assets/Public_School_Characteristics_2020-21_no_prop.geojson',
  });

  map.addLayer({
    id: 'school_heat',
    type: 'heatmap',
    source: 'school_source',
    maxzoom: 14,
    paint: {

      // Increase the heatmap weight based on frequency and property magnitude
      'heatmap-weight': [
        'interpolate',
        ['linear'],
        ['get', 'students'],
        0,
        0,
        20000, // 20k students to reach the max of colormap
        1
      ],

      // Increase the heatmap color weight weight by zoom level
      // heatmap-intensity is a multiplier on top of heatmap-weight
      'heatmap-intensity': [
        'interpolate',
        ['linear'],
        ['zoom'],
        0,
        1,
        12,
        3
      ],

      // Color ramp for heatmap.  Domain is 0 (low) to 1 (high).
      // Begin color ramp at 0-stop with a 0-transparancy color
      // to create a blur-like effect.
      'heatmap-color': [
        'interpolate',
        ['linear'],
        ['heatmap-density'],
        0, "rgba(68, 1, 84, 0)",
        0.01, "rgba(68, 1, 84, 0.2)",
        0.13, "rgba(71, 44, 122, 1)",
        0.25, "rgba(59, 81, 139, 1)",
        0.38, "rgba(44, 113, 142, 1)",
        0.5, "rgba(33, 144, 141, 1)",
        0.63, "rgba(39, 173, 129, 1)",
        0.75, "rgba(92, 200, 99, 1)",
        0.88, "rgba(170, 220, 50, 1)",
        1, "rgba(253, 231, 37, 1)",
      ],

      // Adjust the heatmap radius by zoom level
      'heatmap-radius': [
        'interpolate',
        ['linear'],
        ['zoom'],
        0,
        2,
        9,
        20
      ],
      // Transition from heatmap to circle layer by zoom level
      'heatmap-opacity': [
        'interpolate',
        ['linear'],
        ['zoom'],
        7,
        1,
        18,
        0
      ]
    }
  });

  map.addLayer({
    'id': 'school_point',
    'type': 'circle',
    'source': 'school_source',
    'minzoom': 8,
    'paint': {
      'circle-pitch-alignment': "map",
      // Size circle radius by earthquake magnitude and zoom level
      'circle-radius': [
        'interpolate',
        ['linear'],
        ['zoom'],
        9,
        ['interpolate', ['linear'], ['get', 'students'], 10, 0.1 * 5, 4000, 2 * 2.5],
        16,
        ['interpolate', ['linear'], ['get', 'students'], 10, 1 * 5, 4000, 20 * 2.5]
      ],
      // Color circle by earthquake magnitude
      'circle-color': [
        'interpolate',
        ['linear'],
        ['get', 'students'],
        2000 * 0, "rgba(68, 1, 84, 0)",
        2000 * 0.01, "rgba(68, 1, 84, 20)",
        2000 * 0.13, "rgba(71, 44, 122, 100)",
        2000 * 0.25, "rgba(59, 81, 139, 100)",
        2000 * 0.38, "rgba(44, 113, 142, 100)",
        2000 * 0.5, "rgba(33, 144, 141, 100)",
        2000 * 0.63, "rgba(39, 173, 129, 100)",
        2000 * 0.75, "rgba(92, 200, 99, 100)",
        2000 * 0.88, "rgba(170, 220, 50, 100)",
        2000 * 1, "rgba(253, 231, 37, 100)",
      ],
      // 'circle-stroke-color': 'white',
      'circle-stroke-width': 0,
      // Transition from heatmap to circle layer by zoom level
      'circle-opacity': [
        'interpolate',
        ['linear'],
        ['zoom'],
        8,
        0,
        12,
        0.8
      ]
    }
  });

  await sleepAsync(1000);
  animateMap(); // call custom animation function that will start animating through the locations
});
Display HTML clusters with custom properties

HTML clusters with custom properties

Examples

Enhance map clustering using HTML markers and custom expressions.

Point layer cluster (point helper)

Point layer cluster (point helper)

Examples

Add clustered point layer using MapTiler point helper.

Heatmap layer (heatmap helper)

Heatmap layer (heatmap helper)

Examples

Quickly add a heatmap layer using the heatmap helper.

Fly to a location

Fly to a location

Examples

Smoothly interpolate between locations using the flyTo animation.

Was this helpful?