Skip to main content

Location Wikipedia

|

This example demonstrates how to retrieve and display Wikipedia information for landmarks using the Maps SDK.

Live Demo

Overview

This example shows how to:

  • Search for a specific landmark by name and coordinates
  • Check if Wikipedia information is available for a landmark
  • Request Wikipedia content including title, description, and images
  • Display Wikipedia data in a modal interface

Code Implementation

Imports

First, import the required modules from the SDK:

import {
GemKit,
GemMap,
Coordinates,
SearchService,
ExternalInfoService,
ExternalInfo,
Landmark,
PositionService,
GemError
} from '@magiclane/maps-sdk';

Setup State Variables

Initialize global variables for UI elements:

let map: GemMap | null = null;
let wikiBtn: HTMLButtonElement;
let wikiModal: HTMLDivElement | null = null;

Initialize Map and UI

Setup the map view and Wikipedia button:

index.ts
window.addEventListener('DOMContentLoaded', async () => {
const gemKit = await GemKit.initialize(GEMKIT_TOKEN);
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);

// Wikipedia button
wikiBtn = document.createElement('button');
wikiBtn.innerHTML = `${ICONS.search} Wikipedia`;
styleButton(wikiBtn, '#673ab7', '#7e57c2'); // Purple
wikiBtn.onclick = onLocationWikipediaTap;
document.body.appendChild(wikiBtn);
});

Search for Landmark

Search for the Statue of Liberty using text and coordinates:

index.ts
async function onLocationWikipediaTap() {
showMessage('Searching Wikipedia info...');

const searchResult = await new Promise<Landmark[]>((resolve) => {
SearchService.search({
textFilter: "Statue of Liberty",
referenceCoordinates: new Coordinates({
latitude: 40.53859,
longitude: -73.91619
}),
onCompleteCallback: (err: any, lmks: Landmark[]) => resolve(lmks)
});
});

const lmk = searchResult[0];
if (!ExternalInfoService.hasWikiInfo(lmk)) {
showWikipediaModal(
"Wikipedia info not available",
"The landmark does not have Wikipedia info"
);
return;
}

// Continue to request Wikipedia data...
}

Request Wikipedia Information

Fetch Wikipedia content for the landmark:

index.ts
async function onLocationWikipediaTap() {
// ...previous search code...

const externalInfo = await new Promise<ExternalInfo | null>((resolve) => {
ExternalInfoService.requestWikiInfo(
lmk,
(err: GemError, info: ExternalInfo | null) => resolve(info)
);
});

if (!externalInfo) {
showWikipediaModal("Query failed", "The request to Wikipedia failed");
return;
}

// Optionally request image info
externalInfo.requestWikiImageInfo(
0,
(error, imageInfo) => {
console.log("Wiki image info received:", error, imageInfo);
}
);

const imageUrl = externalInfo.getWikiImageUrl(0);
showWikipediaModal(
externalInfo.wikiPageTitle,
externalInfo.wikiPageDescription,
imageUrl
);
}

Display Wikipedia Modal

Show Wikipedia information in a modal dialog:

index.ts
function showWikipediaModal(title: string, content: string, imageUrl?: string) {
if (wikiModal) document.body.removeChild(wikiModal);

wikiModal = document.createElement('div');
wikiModal.style.cssText = `
position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
background: rgba(0,0,0,0.5); z-index: 3000; display: flex;
align-items: center; justify-content: center;
`;

const panel = document.createElement('div');
panel.style.cssText = `
background: #fff; border-radius: 12px; padding: 24px;
max-width: 600px; width: 90vw; max-height: 80vh; overflow-y: auto;
box-shadow: 0 2px 20px rgba(0,0,0,0.3);
display: flex; flex-direction: column; align-items: center;
`;

// Display Wikipedia image if available
if (imageUrl) {
const img = document.createElement('img');
img.src = imageUrl;
img.alt = title;
img.style.cssText = `
max-width: 100%; max-height: 250px; border-radius: 8px;
margin-bottom: 16px;
`;
panel.appendChild(img);
}

// Title
const titleElem = document.createElement('h2');
titleElem.textContent = title;
titleElem.style.marginTop = '0';
panel.appendChild(titleElem);

// Content
const contentElem = document.createElement('div');
contentElem.style.fontSize = '1.1em';
contentElem.innerHTML = content;
panel.appendChild(contentElem);

// Close button
const closeBtn = document.createElement('button');
closeBtn.textContent = 'Close';
closeBtn.style.cssText = `
margin-top: 12px; padding: 8px 20px; background: #673ab7;
color: #fff; border: none; border-radius: 8px; font-size: 1em;
cursor: pointer;
`;
closeBtn.onclick = () => {
if (wikiModal) document.body.removeChild(wikiModal);
wikiModal = null;
};
panel.appendChild(closeBtn);

wikiModal.appendChild(panel);

// Close on background click
wikiModal.onclick = (e) => {
if (e.target === wikiModal && wikiModal) {
document.body.removeChild(wikiModal);
wikiModal = null;
}
};

document.body.appendChild(wikiModal);
}

Utility Functions

Display temporary status messages:

index.ts
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

Check Wikipedia Availability

Before requesting Wikipedia data, verify it's available:

if (!ExternalInfoService.hasWikiInfo(lmk)) {
// Wikipedia info not available for this landmark
return;
}

This prevents unnecessary API calls for landmarks without Wikipedia entries.

Request Wikipedia Data

Use ExternalInfoService to fetch Wikipedia content:

Method:

ExternalInfoService.requestWikiInfo(
landmark,
(err: GemError, info: ExternalInfo | null) => {
// Handle response
}
);

Parameters:

  • landmark: The Landmark object to get info for
  • callback: Receives error code and ExternalInfo object

Access Wikipedia Content

Extract Wikipedia data from ExternalInfo:

Properties:

  • externalInfo.wikiPageTitle - Wikipedia article title
  • externalInfo.wikiPageDescription - Article content/description
  • externalInfo.getWikiImageUrl(index) - Get image URL at index

Image Information:

externalInfo.requestWikiImageInfo(
0, // Image index
(error, imageInfo) => {
console.log("Image info:", imageInfo);
}
);

Search with Reference Coordinates

Improve search accuracy by providing reference coordinates:

SearchService.search({
textFilter: "Statue of Liberty",
referenceCoordinates: new Coordinates({
latitude: 40.53859,
longitude: -73.91619
}),
onCompleteCallback: callback
});

Reference coordinates help disambiguate landmarks with similar names.

The modal uses modern web design patterns:

Features:

  • Semi-transparent overlay background
  • Centered panel with max dimensions
  • Scrollable content for long Wikipedia articles
  • Click outside to close functionality
  • Responsive design (90vw, 80vh)

Promise-based Async Pattern

Wrap SDK callbacks in Promises for cleaner async code:

const searchResult = await new Promise<Landmark[]>((resolve) => {
SearchService.search({
textFilter: text,
referenceCoordinates: coords,
onCompleteCallback: (err, lmks) => resolve(lmks)
});
});

This enables async/await syntax instead of nested callbacks.

Implementation Details

  • Error Handling: Check for null results and missing Wikipedia data
  • Image Display: Conditionally display images if available
  • HTML Content: Use innerHTML to render formatted Wikipedia text
  • Modal Cleanup: Remove previous modal before creating new one
  • Background Dismiss: Click outside modal to close
  • Loading Feedback: Show "Searching..." message during API calls

Use Cases

  • Tourist Information: Display Wikipedia info for landmarks and monuments
  • Educational Apps: Provide historical context for locations
  • Travel Guides: Show detailed descriptions of destinations
  • Museum Apps: Display information about exhibits and artifacts
  • City Tours: Provide background information for tour stops
  • Cultural Apps: Share historical and cultural context

Next Steps