Ola Map SDK

Examples

Practical code examples and use cases for Ola Map SDK

Examples & Use Cases

Practical examples demonstrating common use cases for the Ola Map SDK.

Table of Contents

Quick Start Examples

Basic Setup

const OlaMapsClient = require('ola-map-sdk');

// Initialize with API key
const client = new OlaMapsClient(process.env.OLA_MAPS_API_KEY);

// Make your first API call
async function getStarted() {
    const results = await client.places.autocomplete('Bangalore');
    console.log('First result:', results.predictions[0]);
}

getStarted();

Using Environment Variables

require('dotenv').config();
const OlaMapsClient = require('ola-map-sdk');

const client = new OlaMapsClient(process.env.OLA_MAPS_API_KEY);

Location Search with Autocomplete

async function searchLocations(query) {
    try {
        const results = await client.places.autocomplete(query, {
            location: '12.9716,77.5946',  // Bangalore center
            radius: 10000,
            types: 'locality'
        });
        
        return results.predictions.map(p => ({
            name: p.description,
            placeId: p.place_id,
            types: p.types
        }));
    } catch (error) {
        console.error('Search failed:', error);
        throw error;
    }
}

// Usage
searchLocations('Koramangala')
    .then(results => console.log('Results:', results))
    .catch(console.error);

Find Nearby Restaurants

async function findNearbyRestaurants(location, radius = 1000) {
    const results = await client.places.nearbySearch(location, {
        types: 'restaurant',
        radius: radius,
        language: 'en',
        limit: 10
    });
    
    return results.results.map(r => ({
        name: r.name,
        address: r.formatted_address,
        rating: r.rating,
        placeId: r.place_id,
        location: r.geometry.location
    }));
}

// Usage
findNearbyRestaurants('12.93,77.61', 2000)
    .then(restaurants => console.log('Restaurants:', restaurants))
    .catch(console.error);

Get Complete Place Details

async function getPlaceInformation(placeId) {
    const details = await client.places.placeDetailsAdvanced(placeId);
    
    return {
        name: details.result.name,
        address: details.result.formatted_address,
        phone: details.result.phone_number,
        website: details.result.website,
        rating: details.result.rating,
        reviews: details.result.user_ratings_total,
        openingHours: details.result.opening_hours?.weekday_text,
        photos: details.result.photos?.slice(0, 3),
        amenities: details.result.amenities
    };
}

// Usage
const placeInfo = await getPlaceInformation('ola-platform:5000039498427');
console.log('Place details:', placeInfo);

Address Geocoding

async function geocodeAddress(address) {
    const result = await client.places.geocode(address);
    
    if (result.results && result.results.length > 0) {
        return {
            formattedAddress: result.results[0].formatted_address,
            latitude: result.results[0].geometry.location.lat,
            longitude: result.results[0].geometry.location.lng,
            placeId: result.results[0].place_id
        };
    }
    
    throw new Error('Address not found');
}

// Usage
geocodeAddress('Phoenix Marketcity, Bangalore')
    .then(location => console.log('Location:', location))
    .catch(console.error);

Reverse Geocoding

async function getAddressFromCoordinates(lat, lng) {
    const result = await client.places.reverseGeocode(lat, lng, 'en');
    
    if (result.results && result.results.length > 0) {
        const address = result.results[0];
        return {
            formattedAddress: address.formatted_address,
            street: address.address_components.find(c => c.types.includes('route'))?.long_name,
            city: address.address_components.find(c => c.types.includes('locality'))?.long_name,
            state: address.address_components.find(c => c.types.includes('administrative_area_level_1'))?.long_name,
            country: address.address_components.find(c => c.types.includes('country'))?.long_name,
            postalCode: address.address_components.find(c => c.types.includes('postal_code'))?.long_name
        };
    }
    
    throw new Error('Location not found');
}

// Usage
getAddressFromCoordinates(12.9716, 77.5946)
    .then(address => console.log('Address:', address))
    .catch(console.error);

Routing & Navigation

Get Directions with Traffic

async function getRouteWithTraffic(origin, destination) {
    const route = await client.routing.getDirections(
        origin,
        destination,
        {
            mode: 'driving',
            steps: true,
            traffic_metadata: true,
            alternatives: true
        }
    );
    
    return route.routes.map(r => ({
        summary: r.summary,
        distance: r.legs[0].distance.text,
        duration: r.legs[0].duration.text,
        durationInTraffic: r.legs[0].duration_in_traffic?.text,
        steps: r.legs[0].steps.map(s => s.html_instructions)
    }));
}

// Usage
getRouteWithTraffic(
    { lat: 12.993103, lon: 77.543326 },
    { lat: 12.972006, lon: 77.580085 }
)
    .then(routes => console.log('Routes:', routes))
    .catch(console.error);

Calculate Travel Times Matrix

async function calculateTravelTimes(origins, destinations) {
    const matrix = await client.routing.getDistanceMatrix(
        origins.join('|'),
        destinations.join('|'),
        { mode: 'driving' }
    );
    
    return matrix.rows.map((row, i) => ({
        origin: origins[i],
        destinations: row.elements.map((elem, j) => ({
            destination: destinations[j],
            distance: elem.distance.text,
            duration: elem.duration.text,
            status: elem.status
        }))
    }));
}

// Usage
const warehouses = ['12.99,77.54', '12.97,77.58'];
const customers = ['12.93,77.61', '12.95,77.62', '12.96,77.63'];

calculateTravelTimes(warehouses, customers)
    .then(matrix => console.log('Travel time matrix:', matrix))
    .catch(console.error);

Optimize Delivery Route

async function optimizeDeliveryRoute(stops) {
    const locations = stops.join('|');
    
    const optimized = await client.routing.routeOptimizer(locations, {
        source: 'first',
        destination: 'last',
        round_trip: false,
        mode: 'driving',
        steps: true
    });
    
    return {
        optimizedOrder: optimized.optimized_order,
        totalDistance: optimized.route.total_distance.text,
        totalTime: optimized.route.total_duration.text,
        directions: optimized.route.legs
    };
}

// Usage
const deliveryStops = [
    '12.99,77.54',  // Warehouse
    '12.97,77.58',  // Stop 1
    '12.93,77.61',  // Stop 2
    '12.95,77.62'   // Stop 3
];

optimizeDeliveryRoute(deliveryStops)
    .then(route => console.log('Optimized route:', route))
    .catch(console.error);

Multi-Vehicle Fleet Planning

async function planFleetRoutes(packages, vehicles) {
    const inputData = {
        packages: packages.map((pkg, idx) => ({
            id: `pkg_${idx}`,
            location: { lat: pkg.lat, lon: pkg.lng },
            demand: pkg.demand || 1,
            time_window: pkg.timeWindow || { start: '09:00', end: '17:00' }
        })),
        vehicles: vehicles.map((veh, idx) => ({
            id: `veh_${idx}`,
            start_location: { lat: veh.startLat, lon: veh.startLng },
            end_location: { lat: veh.endLat, lon: veh.endLng },
            capacity: veh.capacity || 10,
            available_time: veh.availableTime || { start: '08:00', end: '18:00' }
        }))
    };
    
    const result = await client.routing.fleetPlanner(inputData, 'optimal');
    
    return result.solution;
}

// Usage
const packages = [
    { lat: 12.97, lng: 77.58, demand: 2 },
    { lat: 12.93, lng: 77.61, demand: 1 },
    { lat: 12.95, lng: 77.62, demand: 3 }
];

const vehicles = [
    { startLat: 12.99, startLng: 77.54, endLat: 12.99, endLng: 77.54, capacity: 10 }
];

planFleetRoutes(packages, vehicles)
    .then(solution => console.log('Fleet solution:', solution))
    .catch(console.error);

Map Display

Create Interactive Map

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Ola Maps Example</title>
    <script src='https://unpkg.com/maplibre-gl@^4.0.0/dist/maplibre-gl.js'></script>
    <link href='https://unpkg.com/maplibre-gl@^4.0.0/dist/maplibre-gl.css' rel='stylesheet' />
    <style>
        #map { width: 100%; height: 500px; }
    </style>
</head>
<body>
    <div id="map"></div>
    <script>
        const client = new OlaMapsClient('YOUR_API_KEY');
        
        const map = new maplibregl.Map(client.getMapOptions({
            container: 'map',
            center: [77.61, 12.93],
            zoom: 14,
            style: 'default-light-standard'
        }));
        
        // Add navigation controls
        map.addControl(new maplibregl.NavigationControl());
        
        // Add marker
        new maplibregl.Marker()
            .setLngLat([77.61, 12.93])
            .setPopup(new maplibregl.Popup().setHTML('<h3>Bangalore</h3>'))
            .addTo(map);
    </script>
</body>
</html>

Generate Static Map Image

async function generateLocationMap(location, zoom = 15) {
    const imageBuffer = await client.tiles.getStaticMapByCenter(
        'default-light-standard',
        location.lng,
        location.lat,
        zoom,
        600,
        400,
        'png',
        {
            marker: `${location.lng},${location.lat}|red`
        }
    );
    
    // Convert to base64 for web display
    const base64Image = Buffer.from(imageBuffer).toString('base64');
    return `data:image/png;base64,${base64Image}`;
}

// Usage
generateLocationMap({ lat: 12.9716, lng: 77.5946 })
    .then(mapImage => console.log('Map image:', mapImage))
    .catch(console.error);

Switch Map Styles

function setupStyleSwitcher(map) {
    const styles = {
        'Light': 'default-light-standard',
        'Dark': 'default-dark-standard',
        'Eclipse': 'eclipse-light-standard',
        'Vintage': 'vintage-light',
        'Earth': 'default-earth-standard'
    };
    
    const container = document.createElement('div');
    container.className = 'style-switcher';
    
    Object.entries(styles).forEach(([label, styleName]) => {
        const button = document.createElement('button');
        button.textContent = label;
        button.onclick = () => {
            const styleUrl = client.getStyleURL(styleName);
            map.setStyle(styleUrl);
        };
        container.appendChild(button);
    });
    
    map.getContainer().appendChild(container);
}

Real-World Applications

Store Locator Application

class StoreLocator {
    constructor(apiKey) {
        this.client = new OlaMapsClient(apiKey);
        this.map = null;
        this.stores = [];
    }
    
    async initializeMap(center, zoom = 12) {
        this.map = new maplibregl.Map(this.client.getMapOptions({
            container: 'map',
            center: center,
            zoom: zoom
        }));
        
        this.map.addControl(new maplibregl.NavigationControl());
        this.map.addControl(new maplibregl.GeolocateControl());
    }
    
    async loadStores(storesData) {
        this.stores = storesData;
        
        // Clear existing markers
        this.map.getSource('stores')?.setData({ type: 'FeatureCollection', features: [] });
        
        // Add store markers
        const features = storesData.map(store => ({
            type: 'Feature',
            geometry: { type: 'Point', coordinates: [store.lng, store.lat] },
            properties: store
        }));
        
        this.map.addSource('stores', {
            type: 'geojson',
            data: { type: 'FeatureCollection', features }
        });
        
        this.map.addLayer({
            id: 'stores-layer',
            type: 'circle',
            source: 'stores',
            paint: {
                'circle-radius': 8,
                'circle-color': '#0080ff',
                'circle-stroke-width': 2,
                'circle-stroke-color': '#ffffff'
            }
        });
        
        // Add click interaction
        this.map.on('click', 'stores-layer', (e) => {
            const store = e.features[0].properties;
            new maplibregl.Popup()
                .setLngLat(e.lngLat)
                .setHTML(`
                    <h3>${store.name}</h3>
                    <p>${store.address}</p>
                    <p>Phone: ${store.phone}</p>
                `)
                .addTo(this.map);
        });
    }
    
    async searchStores(query) {
        if (!query || query.length < 3) return;
        
        const results = await this.client.places.autocomplete(query, {
            location: '12.9716,77.5946',
            radius: 20000,
            types: 'point_of_interest'
        });
        
        // Filter and display matching stores...
        return results;
    }
}

// Usage
const locator = new StoreLocator('YOUR_API_KEY');
locator.initializeMap([77.61, 12.93]);
locator.loadStores([
    { name: 'Store A', address: 'MG Road', lat: 12.9716, lng: 77.5946, phone: '+91-80-12345678' },
    { name: 'Store B', address: 'Brigade Rd', lat: 12.9720, lng: 77.6000, phone: '+91-80-87654321' }
]);

Delivery Tracking System

class DeliveryTracker {
    constructor(apiKey) {
        this.client = new OlaMapsClient(apiKey);
        this.activeDeliveries = new Map();
    }
    
    async createDelivery(deliveryId, pickupLocation, dropLocation) {
        // Get optimal route
        const route = await this.client.routing.getDirections(
            pickupLocation,
            dropLocation,
            { mode: 'driving', steps: true }
        );
        
        const delivery = {
            id: deliveryId,
            route: route.routes[0],
            status: 'pending',
            currentLocation: null,
            estimatedTime: route.routes[0].legs[0].duration.value
        };
        
        this.activeDeliveries.set(deliveryId, delivery);
        return delivery;
    }
    
    updateDeliveryPosition(deliveryId, currentLocation) {
        const delivery = this.activeDeliveries.get(deliveryId);
        if (!delivery) return;
        
        delivery.currentLocation = currentLocation;
        
        // Check if near any waypoint
        const nearestWaypoint = this.findNearestWaypoint(
            currentLocation,
            delivery.route.legs[0].steps
        );
        
        if (nearestWaypoint) {
            this.notifyCustomer(deliveryId, nearestWaypoint);
        }
    }
    
    findNearestWaypoint(location, steps) {
        // Implementation to find nearest step in route
        return steps.find(step => {
            const distance = this.calculateDistance(
                location.lat, location.lng,
                step.start_location.lat, step.start_location.lng
            );
            return distance < 100; // Within 100 meters
        });
    }
    
    calculateDistance(lat1, lng1, lat2, lng2) {
        const R = 6371e3; // Earth's radius in meters
        const φ1 = lat1 * Math.PI/180;
        const φ2 = lat2 * Math.PI/180;
        const Δφ = (lat2-lat1) * Math.PI/180;
        const Δλ = (lng2-lng1) * Math.PI/180;
        
        const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
                  Math.cos(φ1) * Math.cos(φ2) *
                  Math.sin(Δλ/2) * Math.sin(Δλ/2);
        const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        
        return R * c;
    }
    
    notifyCustomer(deliveryId, waypoint) {
        console.log(`Delivery ${deliveryId} approaching: ${waypoint.html_instructions}`);
        // Send SMS/email notification
    }
}

// Usage
const tracker = new DeliveryTracker('YOUR_API_KEY');

tracker.createDelivery(
    'DEL001',
    { lat: 12.993103, lon: 77.543326 },
    { lat: 12.972006, lon: 77.580085 }
);

// Simulate position updates
setInterval(() => {
    tracker.updateDeliveryPosition('DEL001', { lat: 12.985, lng: 77.560 });
}, 5000);

Service Area Checker

class ServiceAreaChecker {
    constructor(apiKey, projectId) {
        this.client = new OlaMapsClient(apiKey);
        this.projectId = projectId;
        this.serviceAreas = [];
    }
    
    async loadServiceAreas() {
        const response = await this.client.geofencing.list(this.projectId, 1, 100);
        this.serviceAreas = response.data.geofences;
    }
    
    async isServiceable(lat, lng) {
        for (const area of this.serviceAreas) {
            const status = await this.client.geofencing.checkStatus(
                area.id,
                `${lat},${lng}`
            );
            
            if (status.data.isInside) {
                return {
                    serviceable: true,
                    area: area.name,
                    metadata: area.metadata
                };
            }
        }
        
        return { serviceable: false, message: 'Location not in service area' };
    }
    
    async checkBulkLocations(locations) {
        const results = await Promise.all(
            locations.map(loc => this.isServiceable(loc.lat, loc.lng))
        );
        
        return locations.map((loc, idx) => ({
            location: loc,
            ...results[idx]
        }));
    }
}

// Usage
const checker = new ServiceAreaChecker('YOUR_API_KEY', 'service-areas-2024');
await checker.loadServiceAreas();

const isServiceable = await checker.isServiceable(12.9716, 77.5946);
console.log('Service availability:', isServiceable);

const bulkCheck = await checker.checkBulkLocations([
    { lat: 12.97, lng: 77.59 },
    { lat: 12.98, lng: 77.60 },
    { lat: 12.96, lng: 77.61 }
]);
console.log('Bulk check results:', bulkCheck);

Tips & Best Practices

Error Handling Pattern

async function safeApiCall(fn, errorMessage = 'Operation failed') {
    try {
        return await fn();
    } catch (error) {
        if (error.message.includes('API key')) {
            console.error('Authentication error - check your API key');
        } else if (error.message.includes('429')) {
            console.error('Rate limit exceeded - please wait before retrying');
        } else if (error.message.includes('404')) {
            console.error('Resource not found');
        } else {
            console.error(`${errorMessage}:`, error.message);
        }
        throw error;
    }
}

// Usage
safeApiCall(() => client.places.autocomplete('Bangalore'));

Caching Strategy

class CachedOlaClient {
    constructor(apiKey) {
        this.client = new OlaMapsClient(apiKey);
        this.cache = new Map();
        this.cacheExpiry = new Map();
    }
    
    async cachedCall(key, fn, ttl = 3600000) {
        const now = Date.now();
        
        // Check cache
        if (this.cache.has(key) && now < this.cacheExpiry.get(key)) {
            return this.cache.get(key);
        }
        
        // Make API call
        const result = await fn();
        this.cache.set(key, result);
        this.cacheExpiry.set(key, now + ttl);
        
        return result;
    }
    
    async autocomplete(query) {
        return this.cachedCall(
            `autocomplete:${query}`,
            () => this.client.places.autocomplete(query)
        );
    }
    
    async geocode(address) {
        return this.cachedCall(
            `geocode:${address}`,
            () => this.client.places.geocode(address),
            86400000 // 24 hours
        );
    }
}

Rate Limiting

class RateLimitedClient {
    constructor(apiKey, requestsPerSecond = 10) {
        this.client = new OlaMapsClient(apiKey);
        this.queue = [];
        this.processing = false;
        this.delay = 1000 / requestsPerSecond;
    }
    
    async request(fn) {
        return new Promise((resolve, reject) => {
            this.queue.push({ fn, resolve, reject });
            this.processQueue();
        });
    }
    
    async processQueue() {
        if (this.processing || this.queue.length === 0) return;
        
        this.processing = true;
        
        while (this.queue.length > 0) {
            const { fn, resolve, reject } = this.queue.shift();
            
            try {
                const result = await fn();
                resolve(result);
            } catch (error) {
                reject(error);
            }
            
            if (this.queue.length > 0) {
                await new Promise(r => setTimeout(r, this.delay));
            }
        }
        
        this.processing = false;
    }
}

// Usage
const rateLimitedClient = new RateLimitedClient('YOUR_API_KEY', 5);

// Make multiple requests without hitting rate limits
Promise.all([
    rateLimitedClient.request(() => client.places.autocomplete('A')),
    rateLimitedClient.request(() => client.places.autocomplete('B')),
    rateLimitedClient.request(() => client.places.autocomplete('C'))
]);

These examples demonstrate practical implementations using the Ola Map SDK. For more specific use cases or questions, visit the GitHub repository.

On this page