Skip to main content

Display Cursor Street Name

Last updated: January 27, 2026 | 5 minutes read

This example demonstrates how to display the name of the street at the cursor position when users tap on the map.

Live Demo

Overview

This example shows how to:

  • Enable cursor rendering on the map
  • Register touch callbacks to detect tap positions
  • Set cursor position based on screen coordinates
  • Retrieve street information at the cursor location
  • Display street names in a UI overlay

Code Implementation

Imports

First, import the required modules from the SDK:

import {
GemKit,
GemMap,
Coordinates,
PositionService
} from '@magiclane/maps-sdk';

Setup State Variables

Initialize global variables for map and UI elements:

let map: GemMap | null = null;
let currentStreetName = "";

// UI Elements
let streetNameDiv: HTMLDivElement;

Initialize Map with Cursor

Setup the map centered on Milan, Italy with cursor enabled:

async function onMapCreated(gemMap: GemMap) {
map = gemMap;

// Center on Milan, Italy
map.centerOnCoordinates(new Coordinates({
latitude: 45.472358,
longitude: 9.184945
}), { zoomLevel: 80 });

// Enable cursor rendering
map.preferences.enableCursor = true;
map.preferences.enableCursorRender = true;

// Register touch callback to set cursor and display street name
map.registerTouchCallback(async (point: any) => {
await map!.setCursorScreenPosition(point);
const streets = map!.cursorSelectionStreets();
currentStreetName = (streets && streets.length > 0)
? (streets[0].name || "Unnamed street")
: "Unnamed street";
updateStreetNameUI(currentStreetName);
});
}

Initialize GemKit and Map View

Setup the map container and initialize the SDK:

window.addEventListener('DOMContentLoaded', async () => {
const gemKit = await GemKit.initialize(projectApiToken);
await PositionService.instance;

const container = document.getElementById('map-container');
if (!container) throw new Error('Map container not found');

const viewId = 2;
const wrapper = gemKit.createView(viewId, onMapCreated);
if (wrapper) container.appendChild(wrapper);

// Create the street name display (hidden by default)
updateStreetNameUI("");
});

Display Street Name UI

Create and update the street name overlay:

function updateStreetNameUI(name: string) {
if (!streetNameDiv) {
streetNameDiv = document.createElement('div');
streetNameDiv.style.cssText = `
position: fixed; bottom: 25px; left: 50%; transform: translateX(-50%);
background: #fff; color: #222; border-radius: 8px; padding: 8px 16px;
font-size: 1.1em; box-shadow: 0 2px 10px rgba(0,0,0,0.15); z-index: 2000;
min-width: 120px; text-align: center;
`;
document.body.appendChild(streetNameDiv);
}
streetNameDiv.textContent = name;
streetNameDiv.style.display = name ? 'block' : 'none';
}

Utility Functions

Display temporary status messages:

function showMessage(message: string, duration = 3000) {
let msgDiv = document.getElementById('status-msg');
if (!msgDiv) {
msgDiv = document.createElement('div');
msgDiv.id = 'status-msg';
msgDiv.style.cssText = `
position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
background: #333; color: #fff; padding: 12px 20px; border-radius: 8px;
z-index: 2000; font-size: 1em;
`;
document.body.appendChild(msgDiv);
}
msgDiv.textContent = message;
setTimeout(() => {
msgDiv.textContent = '';
}, duration);
}

Key Features

Enable Cursor

Configure map preferences to enable cursor functionality:

map.preferences.enableCursor = true;
map.preferences.enableCursorRender = true;

Properties:

  • enableCursor - Enable cursor detection and selection
  • enableCursorRender - Render cursor visually on map

Touch Callback Registration

Register a callback to handle tap events:

map.registerTouchCallback(async (point: any) => {
// Handle touch event
});

Callback Parameter:

  • point - Screen coordinates {x, y} where user tapped

Set Cursor Position

Update cursor to tapped screen position:

await map.setCursorScreenPosition(point);

This method:

  • Sets the cursor to the specified screen coordinates
  • Triggers internal selection logic
  • Enables retrieval of street information

Retrieve Street Information

Get streets at cursor position:

const streets = map.cursorSelectionStreets();

Return Value:

  • Array of street objects at cursor location
  • Each street has a name property
  • Empty array if no streets found

Handle Unnamed Streets

Provide fallback for streets without names:

currentStreetName = (streets && streets.length > 0)
? (streets[0].name || "Unnamed street")
: "Unnamed street";

This ensures the UI always displays meaningful text.

Dynamic UI Display

Show/hide street name based on availability:

streetNameDiv.style.display = name ? 'block' : 'none';

The overlay only appears when a street name is available.

Bottom-Centered Overlay

Position the street name at the bottom center:

position: fixed;
bottom: 25px;
left: 50%;
transform: translateX(-50%);

This creates a clear, non-intrusive display area.

Implementation Details

  • Lazy Initialization: Street name div created on first use
  • Async Operations: setCursorScreenPosition is awaited before retrieving streets
  • Null Checking: Verify streets array exists and has elements
  • Fallback Text: Display "Unnamed street" for unnamed or missing streets
  • Visual Design: White background with shadow for readability
  • Z-index: 2000 ensures overlay appears above map
  • Centering: Transform translate for perfect horizontal centering

Use Cases

  • Navigation Apps: Show current street name during navigation
  • Real Estate Apps: Display property street information
  • Delivery Apps: Confirm delivery address street
  • City Exploration: Learn street names while browsing the map
  • Address Selection: Help users confirm selected location
  • Educational Apps: Teach geography and street layouts
  • Tourist Apps: Identify street names in foreign cities

Advanced Features

Multiple Streets

Handle intersections with multiple streets:

if (streets && streets.length > 1) {
const streetNames = streets.map(s => s.name).join(" / ");
updateStreetNameUI(streetNames);
}

Street Details

Access additional street properties:

streets.forEach(street => {
console.log('Street:', street.name);
console.log('Type:', street.type);
// Additional properties may be available
});

Custom Styling

Customize the overlay appearance:

streetNameDiv.style.cssText = `
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
font-weight: bold;
border: 2px solid #fff;
`;

Next Steps