Interactive overlay components including markers and popups for displaying information and providing user interaction points on the map.
Point marker overlay that can display custom elements and bind popups for user interaction.
/**
* Creates a new Marker instance
* @param options - Configuration options for the marker
*/
class Marker extends Evented {
constructor(options?: MarkerOptions);
// Map management
addTo(map: Map): Marker;
remove(): Marker;
// Position management
setLngLat(lnglat: LngLatLike): Marker;
getLngLat(): LngLat;
// Styling and positioning
setOffset(offset: PointLike): Marker;
getOffset(): Point;
setRotation(rotation: number): Marker;
getRotation(): number;
setAltitude(altitude: number): Marker;
getAltitude(): number;
// Alignment properties
setRotationAlignment(alignment: 'auto' | 'map' | 'viewport' | 'horizon'): Marker;
getRotationAlignment(): string;
setPitchAlignment(alignment: 'auto' | 'map' | 'viewport'): Marker;
getPitchAlignment(): string;
// Occlusion handling
setOccludedOpacity(opacity: number): Marker;
getOccludedOpacity(): number;
// Interaction
setDraggable(draggable: boolean): Marker;
isDraggable(): boolean;
// CSS class management
addClassName(className: string): Marker;
removeClassName(className: string): Marker;
toggleClassName(className: string): boolean;
// Popup integration
setPopup(popup?: Popup): Marker;
getPopup(): Popup | undefined;
togglePopup(): Marker;
// DOM access
getElement(): HTMLElement;
}
interface MarkerOptions {
element?: HTMLElement;
offset?: PointLike;
anchor?: Anchor;
color?: string;
scale?: number;
draggable?: boolean;
clickTolerance?: number;
rotation?: number;
rotationAlignment?: 'map' | 'viewport' | 'auto';
pitchAlignment?: 'map' | 'viewport' | 'auto';
occludedOpacity?: number;
className?: string;
altitude?: number;
}Usage Examples:
import mapboxgl from 'mapbox-gl';
// Basic marker
const marker = new mapboxgl.Marker()
.setLngLat([-74.006, 40.7128])
.addTo(map);
// Custom colored marker
const redMarker = new mapboxgl.Marker({ color: '#ff0000' })
.setLngLat([-74.006, 40.7128])
.addTo(map);
// Custom HTML element marker
const el = document.createElement('div');
el.className = 'custom-marker';
el.style.backgroundImage = 'url(marker-icon.png)';
el.style.width = '32px';
el.style.height = '32px';
const customMarker = new mapboxgl.Marker(el)
.setLngLat([-74.006, 40.7128])
.addTo(map);
// Draggable marker with event handling
const draggableMarker = new mapboxgl.Marker({ draggable: true })
.setLngLat([-74.006, 40.7128])
.addTo(map);
draggableMarker.on('dragend', () => {
const lngLat = draggableMarker.getLngLat();
console.log(`Marker moved to: ${lngLat.lng}, ${lngLat.lat}`);
});
// Marker with popup
const popup = new mapboxgl.Popup({ offset: 25 })
.setHTML('<h3>Hello World!</h3><p>This is a popup.</p>');
const markerWithPopup = new mapboxgl.Marker()
.setLngLat([-74.006, 40.7128])
.setPopup(popup)
.addTo(map);Information popup overlay with HTML content that can be attached to markers or displayed at specific coordinates.
/**
* Creates a new Popup instance
* @param options - Configuration options for the popup
*/
class Popup extends Evented {
constructor(options?: PopupOptions);
// Map management
addTo(map: Map): Popup;
remove(): Popup;
// State management
isOpen(): boolean;
// Position management
setLngLat(lnglat: LngLatLike): Popup;
getLngLat(): LngLat | undefined;
setAltitude(altitude: number): Popup;
getAltitude(): number;
trackPointer(): Popup;
// Content management
setHTML(html: string): Popup;
setText(text: string): Popup;
setDOMContent(htmlNode: Node): Popup;
// Styling and positioning
setOffset(offset: Offset): Popup;
setMaxWidth(maxWidth: string): Popup;
getMaxWidth(): string | undefined;
// CSS class management
addClassName(className: string): Popup;
removeClassName(className: string): Popup;
toggleClassName(className: string): Popup;
}
interface PopupOptions {
closeButton?: boolean;
closeOnClick?: boolean;
closeOnMove?: boolean;
focusAfterOpen?: boolean;
anchor?: Anchor;
offset?: Offset;
className?: string;
maxWidth?: string;
altitude?: number;
}
type Offset = number | PointLike | Partial<Record<Anchor, PointLike>>;Usage Examples:
import mapboxgl from 'mapbox-gl';
// Basic popup
const popup = new mapboxgl.Popup()
.setLngLat([-74.006, 40.7128])
.setHTML('<h3>New York City</h3><p>The most populous city in the United States.</p>')
.addTo(map);
// Popup with custom styling
const styledPopup = new mapboxgl.Popup({
closeButton: false,
closeOnClick: false,
className: 'custom-popup',
maxWidth: '300px',
offset: 25
})
.setLngLat([-74.006, 40.7128])
.setHTML('<div class="popup-content"><h3>Custom Popup</h3></div>')
.addTo(map);
// Popup with DOM content
const contentDiv = document.createElement('div');
contentDiv.innerHTML = '<h3>Dynamic Content</h3><button onclick="handleClick()">Click Me</button>';
const domPopup = new mapboxgl.Popup()
.setLngLat([-74.006, 40.7128])
.setDOMContent(contentDiv)
.addTo(map);
// Popup that appears on map click
map.on('click', (e) => {
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(`<h3>Clicked Location</h3><p>Coordinates: ${e.lngLat.lng.toFixed(4)}, ${e.lngLat.lat.toFixed(4)}</p>`)
.addTo(map);
});
// Popup with conditional anchor positioning
const smartPopup = new mapboxgl.Popup({
offset: {
'top': [0, 0],
'top-left': [0, 0],
'top-right': [0, 0],
'bottom': [0, -40],
'bottom-left': [25, -40],
'bottom-right': [-25, -40],
'left': [25, -20],
'right': [-25, -20]
}
})
.setLngLat([-74.006, 40.7128])
.setHTML('<h3>Smart Positioned Popup</h3>')
.addTo(map);Both Marker and Popup classes extend Evented and support event listeners for user interactions.
// Marker events
interface MarkerEvents {
'dragstart': void;
'drag': void;
'dragend': void;
}
// Popup events
interface PopupEvents {
'open': void;
'close': void;
}Usage Examples:
// Marker event handling
const marker = new mapboxgl.Marker({ draggable: true })
.setLngLat([-74.006, 40.7128])
.addTo(map);
marker.on('dragstart', () => {
console.log('Marker drag started');
});
marker.on('drag', () => {
console.log('Marker is being dragged');
});
marker.on('dragend', () => {
const lngLat = marker.getLngLat();
console.log(`Marker drag ended at: ${lngLat.lng}, ${lngLat.lat}`);
});
// Popup event handling
const popup = new mapboxgl.Popup()
.setLngLat([-74.006, 40.7128])
.setHTML('<h3>Event Popup</h3>')
.addTo(map);
popup.on('open', () => {
console.log('Popup opened');
});
popup.on('close', () => {
console.log('Popup closed');
});// Create a marker manager for handling multiple markers
class MarkerManager {
private markers: Map<string, mapboxgl.Marker> = new Map();
addMarker(id: string, lngLat: [number, number], options?: MarkerOptions) {
if (this.markers.has(id)) {
this.removeMarker(id);
}
const marker = new mapboxgl.Marker(options)
.setLngLat(lngLat)
.addTo(map);
this.markers.set(id, marker);
return marker;
}
removeMarker(id: string) {
const marker = this.markers.get(id);
if (marker) {
marker.remove();
this.markers.delete(id);
}
}
clearAll() {
this.markers.forEach(marker => marker.remove());
this.markers.clear();
}
}
const markerManager = new MarkerManager();// Create popups with interactive content
function createInteractivePopup(feature: any) {
const popup = new mapboxgl.Popup({ offset: 25 });
// Create interactive content
const content = document.createElement('div');
content.className = 'interactive-popup';
const title = document.createElement('h3');
title.textContent = feature.properties.name;
content.appendChild(title);
const button = document.createElement('button');
button.textContent = 'View Details';
button.onclick = () => {
// Handle button click
showDetails(feature.properties.id);
popup.remove();
};
content.appendChild(button);
return popup.setDOMContent(content);
}// Anchor positioning for popups and markers
type Anchor =
| 'center'
| 'top'
| 'bottom'
| 'left'
| 'right'
| 'top-left'
| 'top-right'
| 'bottom-left'
| 'bottom-right';
// Point-like coordinate representation
type PointLike = Point | [number, number];
// Geographic coordinate representation
type LngLatLike = LngLat | [number, number] | { lng: number; lat: number } | { lon: number; lat: number };