Skip to content

Set Pitch and Bearing

Control the map's pitch (tilt angle) and bearing (rotation) to create 3D perspectives and directional views.

How It Works

  • Pitch — Tilt the camera from 0° (top-down) to 85° (nearly horizontal)
  • Bearing — Rotate the map from -180° to 180° (0° = North up)

Basic Usage

javascript
// Set pitch (tilt) - 0 is flat, 60 is a strong tilt
map.setPitch(60);

// Set bearing (rotation) - 0 is North up, 90 is East up
map.setBearing(45);

// Set both at once with animation
map.easeTo({
  pitch: 60,
  bearing: -30,
  duration: 1000  // milliseconds
});

Initial Map Configuration

javascript
const map = new mapmetricsgl.Map({
  container: 'map',
  style: '<StyleFile_URL_with_Token>',
  center: [2.349902, 48.852966],
  zoom: 14,
  pitch: 45,    // Start tilted
  bearing: -17  // Start slightly rotated
});

Common Presets

javascript
// Flat top-down view
map.easeTo({ pitch: 0, bearing: 0 });

// Street-level perspective
map.easeTo({ pitch: 60, bearing: 0 });

// Bird's eye diagonal
map.easeTo({ pitch: 45, bearing: -45 });

// North-up reset
map.setBearing(0);

Complete Example

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
    <script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
    <style>
      #map { height: 500px; width: 100%; }
      .controls { margin-top: 12px; }
      .slider-row { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
      label { width: 80px; font-weight: bold; }
      input[type=range] { flex: 1; }
      .buttons { display: flex; gap: 8px; margin-top: 10px; }
      button { padding: 8px 16px; background: #3b82f6; color: white; border: none; border-radius: 6px; cursor: pointer; }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <div class="controls">
      <div class="slider-row">
        <label>Pitch:</label>
        <input id="pitch" type="range" min="0" max="85" value="0" />
        <span id="pitch-val">0°</span>
      </div>
      <div class="slider-row">
        <label>Bearing:</label>
        <input id="bearing" type="range" min="-180" max="180" value="0" />
        <span id="bearing-val">0°</span>
      </div>
      <div class="buttons">
        <button onclick="map.easeTo({pitch:60,bearing:0,duration:1000})">Street View</button>
        <button onclick="map.easeTo({pitch:45,bearing:-45,duration:1000})">Bird's Eye</button>
        <button onclick="map.easeTo({pitch:0,bearing:0,duration:1000})">Reset</button>
      </div>
    </div>
    <script>
      const map = new mapmetricsgl.Map({
        container: 'map',
        style: '<StyleFile_URL_with_Token>',
        center: [2.349902, 48.852966],
        zoom: 14,
        pitch: 0,
        bearing: 0
      });
      map.addControl(new mapmetricsgl.NavigationControl(), 'top-right');

      document.getElementById('pitch').addEventListener('input', (e) => {
        map.setPitch(Number(e.target.value));
        document.getElementById('pitch-val').textContent = e.target.value + '°';
      });

      document.getElementById('bearing').addEventListener('input', (e) => {
        map.setBearing(Number(e.target.value));
        document.getElementById('bearing-val').textContent = e.target.value + '°';
      });
    </script>
  </body>
</html>
jsx
import React, { useEffect, useRef, useState } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';

const SetPitchBearing = () => {
  const mapContainer = useRef(null);
  const map = useRef(null);
  const [pitch, setPitchState] = useState(0);
  const [bearing, setBearingState] = useState(0);

  useEffect(() => {
    if (map.current) return;

    map.current = new mapmetricsgl.Map({
      container: mapContainer.current,
      style: '<StyleFile_URL_with_Token>',
      center: [2.349902, 48.852966],
      zoom: 14,
      pitch: 0,
      bearing: 0
    });
    map.current.addControl(new mapmetricsgl.NavigationControl(), 'top-right');

    return () => { map.current?.remove(); map.current = null; };
  }, []);

  const handlePitch = (val) => {
    setPitchState(val);
    map.current?.setPitch(val);
  };

  const handleBearing = (val) => {
    setBearingState(val);
    map.current?.setBearing(val);
  };

  const preset = (p, b) => {
    map.current?.easeTo({ pitch: p, bearing: b, duration: 1000 });
    setPitchState(p);
    setBearingState(b);
  };

  return (
    <div>
      <div ref={mapContainer} style={{ height: '500px', width: '100%' }} />
      <div style={{ marginTop: '12px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '8px' }}>
          <label style={{ width: '80px', fontWeight: 'bold' }}>Pitch:</label>
          <input type="range" min="0" max="85" value={pitch} onChange={e => handlePitch(Number(e.target.value))} style={{ flex: 1 }} />
          <span style={{ width: '40px' }}>{pitch}°</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
          <label style={{ width: '80px', fontWeight: 'bold' }}>Bearing:</label>
          <input type="range" min="-180" max="180" value={bearing} onChange={e => handleBearing(Number(e.target.value))} style={{ flex: 1 }} />
          <span style={{ width: '40px' }}>{bearing}°</span>
        </div>
        <div style={{ display: 'flex', gap: '8px', marginTop: '10px' }}>
          <button onClick={() => preset(60, 0)} style={{ padding: '8px 16px', background: '#3b82f6', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer' }}>Street View</button>
          <button onClick={() => preset(45, -45)} style={{ padding: '8px 16px', background: '#3b82f6', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer' }}>Bird's Eye</button>
          <button onClick={() => preset(0, 0)} style={{ padding: '8px 16px', background: '#6b7280', color: 'white', border: 'none', borderRadius: '6px', cursor: 'pointer' }}>Reset</button>
        </div>
      </div>
    </div>
  );
};

export default SetPitchBearing;

For more information, visit the MapMetrics GitHub repository.