Ola Map SDK

Geofencing API

Complete guide to creating and managing geofences with the Geofencing API

Geofencing API

The Geofencing API allows you to create, manage, and monitor virtual geographic boundaries for tracking and location-based triggers.

Overview

The Geofencing API provides comprehensive geofence management:

  • Create - Create new geofences (circle or polygon)
  • Read - Get geofence details by ID
  • Update - Modify existing geofences
  • Delete - Remove geofences
  • List - Retrieve all geofences in a project
  • Status Check - Check if coordinates are inside/outside a geofence

Create Geofence

Create a new virtual boundary.

Create Circular Geofence

const fence = await client.geofencing.create({
    name: 'Warehouse Delhi',
    type: 'circle',
    coordinates: [[28.7041, 77.1025]],  // Center point [lat, lng]
    radius: 100,                         // Radius in meters
    status: 'active',
    projectId: 'my-project-001'
});

Create Polygon Geofence

const fence = await client.geofencing.create({
    name: 'Office Campus',
    type: 'polygon',
    coordinates: [
        [12.9352, 77.6245],
        [12.9360, 77.6250],
        [12.9355, 77.6260],
        [12.9345, 77.6255]
    ],
    status: 'active',
    projectId: 'my-project-001'
});

With Metadata

const fence = await client.geofencing.create({
    name: 'Delivery Zone - South',
    type: 'circle',
    coordinates: [[12.9352, 77.6245]],
    radius: 500,
    status: 'active',
    projectId: 'delivery-zones',
    metadata: {
        zoneType: 'delivery',
        priority: 'high',
        operatingHours: '09:00-21:00'
    }
});

Parameters

ParameterTypeRequiredDescription
namestringYesDescriptive name for the geofence
typestringYescircle or polygon
coordinatesarrayYesFor circle: [[lat, lng]], For polygon: [[lat, lng], ...]
radiusnumberConditionalRequired for circle type (in meters)
statusstringNoactive or inactive (default: active)
projectIdstringYesProject identifier
metadataobjectNoCustom metadata object

Response Example

{
    status: "success",
    data: {
        id: "geo_abc123xyz",
        name: "Warehouse Delhi",
        type: "circle",
        coordinates: [[28.7041, 77.1025]],
        radius: 100,
        status: "active",
        projectId: "my-project-001",
        createdAt: "2024-01-15T10:30:00Z",
        updatedAt: "2024-01-15T10:30:00Z"
    }
}

Read Geofence

Retrieve geofence details by ID.

Basic Usage

const geofence = await client.geofencing.getById('geo_abc123xyz');

Response Example

{
    status: "success",
    data: {
        id: "geo_abc123xyz",
        name: "Warehouse Delhi",
        type: "circle",
        coordinates: [[28.7041, 77.1025]],
        radius: 100,
        status: "active",
        projectId: "my-project-001",
        metadata: {
            manager: "John Doe",
            contact: "+91-9876543210"
        },
        createdAt: "2024-01-15T10:30:00Z",
        updatedAt: "2024-01-15T10:30:00Z"
    }
}

Update Geofence

Modify an existing geofence.

Update Basic Properties

const updated = await client.geofencing.update('geo_abc123xyz', {
    name: 'Warehouse Delhi - Expanded',
    radius: 150
});

Update Status

// Temporarily disable geofence
await client.geofencing.update('geo_abc123xyz', {
    status: 'inactive'
});

// Reactivate geofence
await client.geofencing.update('geo_abc123xyz', {
    status: 'active'
});

Update Coordinates

// Change polygon shape
await client.geofencing.update('geo_polygon456', {
    coordinates: [
        [12.9352, 77.6245],
        [12.9365, 77.6255],
        [12.9358, 77.6265],
        [12.9342, 77.6252]
    ]
});

Add Metadata

await client.geofencing.update('geo_abc123xyz', {
    metadata: {
        manager: "Jane Smith",
        contact: "+91-9876543210",
        notes: "Main distribution center"
    }
});

Parameters

ParameterTypeRequiredDescription
idstringYesGeofence ID to update
dataobjectYesFields to update
data.namestringNoNew name
data.coordinatesarrayNoNew coordinates
data.radiusnumberNoNew radius (for circles)
data.statusstringNoactive or inactive
data.metadataobjectNoUpdated metadata

Delete Geofence

Remove a geofence permanently.

Basic Usage

const result = await client.geofencing.deleteById('geo_abc123xyz');

Response Example

{
    status: "success",
    message: "Geofence deleted successfully",
    deletedId: "geo_abc123xyz"
}

Bulk Deletion

async function deleteMultipleGeofences(geofenceIds) {
    const results = await Promise.allSettled(
        geofenceIds.map(id => client.geofencing.deleteById(id))
    );
    
    return results.map((result, index) => ({
        id: geofenceIds[index],
        success: result.status === 'fulfilled',
        error: result.reason?.message
    }));
}

// Usage
deleteMultipleGeofences(['geo_1', 'geo_2', 'geo_3'])
    .then(results => console.log('Deletion results:', results));

List Geofences

Retrieve all geofences for a project.

Basic Usage

const geofences = await client.geofencing.list('my-project-001', 1, 10);

With Pagination

// Get first page (10 items)
const page1 = await client.geofencing.list('project-001', 1, 10);

// Get second page
const page2 = await client.geofencing.list('project-001', 2, 10);

Parameters

ParameterTypeRequiredDescription
projectIdstringYesProject identifier
pagenumberNoPage number (default: 1)
sizenumberNoItems per page (default: 10, max: 100)

Response Example

{
    status: "success",
    data: {
        geofences: [
            {
                id: "geo_001",
                name: "Warehouse Delhi",
                type: "circle",
                status: "active"
            },
            {
                id: "geo_002",
                name: "Office Campus",
                type: "polygon",
                status: "active"
            }
        ],
        pagination: {
            currentPage: 1,
            pageSize: 10,
            totalItems: 25,
            totalPages: 3
        }
    }
}

Check Status

Determine if coordinates are inside or outside a geofence.

Basic Usage

const status = await client.geofencing.checkStatus(
    'geo_abc123xyz',
    '28.7041,77.1025'  // lat,lng format
);

Multiple Location Checks

async function checkMultipleLocations(geofenceId, locations) {
    const checks = await Promise.all(
        locations.map(loc => 
            client.geofencing.checkStatus(geofenceId, `${loc.lat},${loc.lng}`)
        )
    );
    
    return locations.map((loc, idx) => ({
        location: loc,
        insideGeofence: checks[idx].data.isInside,
        geofenceName: checks[idx].data.geofenceName
    }));
}

// Usage
const locations = [
    { lat: 28.7041, lng: 77.1025 },
    { lat: 28.7050, lng: 77.1030 },
    { lat: 28.7030, lng: 77.1020 }
];

checkMultipleLocations('geo_warehouse', locations)
    .then(results => console.log('Location status:', results));

Response Example

{
    status: "success",
    data: {
        geofenceId: "geo_abc123xyz",
        geofenceName: "Warehouse Delhi",
        coordinates: {
            latitude: 28.7041,
            longitude: 77.1025
        },
        isInside: true,
        distance: 45.3,  // meters from center (for circles)
        timestamp: "2024-01-15T11:00:00Z"
    }
}

Real-World Examples

Fleet Management System

Track vehicles entering/exiting designated zones:

class FleetGeofenceManager {
    constructor(client, projectId) {
        this.client = client;
        this.projectId = projectId;
    }
    
    async createDepot(depotData) {
        return await this.client.geofencing.create({
            name: `${depotData.name} Depot`,
            type: 'circle',
            coordinates: [[depotData.lat, depotData.lng]],
            radius: depotData.radius || 200,
            status: 'active',
            projectId: this.projectId,
            metadata: {
                type: 'depot',
                capacity: depotData.capacity,
                manager: depotData.manager
            }
        });
    }
    
    async checkVehicleInZone(vehicleLocation, geofenceId) {
        const status = await this.client.geofencing.checkStatus(
            geofenceId,
            `${vehicleLocation.lat},${vehicleLocation.lng}`
        );
        
        return {
            vehicleId: vehicleLocation.id,
            geofenceId: status.data.geofenceId,
            isInside: status.data.isInside,
            timestamp: new Date().toISOString()
        };
    }
    
    async getAllActiveGeofences() {
        const allGeofences = [];
        let page = 1;
        
        while (true) {
            const response = await this.client.geofencing.list(this.projectId, page, 100);
            const activeOnes = response.data.geofences.filter(g => g.status === 'active');
            allGeofences.push(...activeOnes);
            
            if (response.data.pagination.currentPage >= response.data.pagination.totalPages) {
                break;
            }
            page++;
        }
        
        return allGeofences;
    }
}

// Usage
const fleetManager = new FleetGeofenceManager(client, 'fleet-proj-001');

// Create a new depot
fleetManager.createDepot({
    name: 'North Delhi',
    lat: 28.7041,
    lng: 77.1025,
    radius: 300,
    capacity: 50
});

Delivery Zone Management

Manage delivery service areas:

async function setupDeliveryZones() {
    const zones = [
        {
            name: 'South Delhi Delivery',
            type: 'circle',
            coordinates: [[28.5355, 77.3910]],
            radius: 5000
        },
        {
            name: 'Central Delhi Delivery',
            type: 'circle',
            coordinates: [[28.6139, 77.2090]],
            radius: 3000
        }
    ];
    
    const createdZones = await Promise.all(
        zones.map(zone => 
            client.geofencing.create({
                ...zone,
                status: 'active',
                projectId: 'delivery-2024',
                metadata: {
                    zoneType: 'delivery',
                    deliveryFee: 50,
                    estimatedTime: '30-45 mins'
                }
            })
        )
    );
    
    return createdZones;
}

async function checkDeliveryAvailability(customerLat, customerLng) {
    const zones = await client.geofencing.list('delivery-2024', 1, 50);
    
    for (const zone of zones.data.geofences) {
        const status = await client.geofencing.checkStatus(
            zone.id,
            `${customerLat},${customerLng}`
        );
        
        if (status.data.isInside) {
            return {
                available: true,
                zone: zone.name,
                deliveryFee: zone.metadata.deliveryFee,
                estimatedTime: zone.metadata.estimatedTime
            };
        }
    }
    
    return { available: false, message: 'Location not in delivery zone' };
}

Asset Tracking

Monitor valuable assets within defined areas:

class AssetTracker {
    async createAssetZone(assetId, coordinates, radius = 100) {
        const result = await client.geofencing.create({
            name: `Asset ${assetId} Safe Zone`,
            type: 'circle',
            coordinates: [coordinates],
            radius: radius,
            status: 'active',
            projectId: 'asset-tracking',
            metadata: {
                assetId: assetId,
                alertOnExit: true,
                notificationEmail: 'security@company.com'
            }
        });
        
        return result.data.id;
    }
    
    async monitorAsset(assetId, currentLocation) {
        const geofences = await client.geofencing.list('asset-tracking', 1, 100);
        const assetFence = geofences.data.geofences.find(
            g => g.metadata?.assetId === assetId
        );
        
        if (!assetFence) {
            throw new Error(`No geofence found for asset ${assetId}`);
        }
        
        const status = await client.geofencing.checkStatus(
            assetFence.id,
            `${currentLocation.lat},${currentLocation.lng}`
        );
        
        if (!status.data.isInside && assetFence.metadata.alertOnExit) {
            await this.sendAlert(assetId, status.data);
        }
        
        return status.data;
    }
    
    async sendAlert(assetId, data) {
        // Implement your alert mechanism here
        console.log(`ALERT: Asset ${assetId} has left the designated zone!`);
        console.log(`Last known location: ${data.coordinates.latitude}, ${data.coordinates.longitude}`);
    }
}

Best Practices

1. Organize with Projects

Use different projects for different environments or use cases:

// Separate projects for different purposes
const devProject = 'dev-geofences';
const prodProject = 'prod-geofences';
const testingProject = 'testing-geofences';

// Create geofences in appropriate project
await client.geofencing.create({
    name: 'Test Zone',
    type: 'circle',
    coordinates: [[12.9352, 77.6245]],
    radius: 100,
    projectId: testingProject
});

2. Use Meaningful Names

// ❌ Poor naming
await client.geofencing.create({
    name: 'Zone 1',
    // ...
});

// ✅ Descriptive naming
await client.geofencing.create({
    name: 'Mumbai-Warehouse-A-Zone',
    // ...
});

3. Leverage Metadata

Store important context in metadata:

await client.geofencing.create({
    name: 'Delhi Distribution Center',
    type: 'circle',
    coordinates: [[28.7041, 77.1025]],
    radius: 200,
    projectId: 'logistics',
    metadata: {
        facilityType: 'distribution',
        operatingHours: '06:00-22:00',
        contactPerson: 'Rajesh Kumar',
        contactPhone: '+91-9876543210',
        capacity: '500 units',
        securityLevel: 'high'
    }
});

4. Handle Errors Gracefully

try {
    const fence = await client.geofencing.create(geofenceData);
    console.log('Geofence created:', fence.data.id);
} catch (error) {
    if (error.message.includes('invalid coordinates')) {
        console.error('Invalid coordinates provided');
    } else if (error.message.includes('project not found')) {
        console.error('Project ID does not exist');
    } else {
        console.error('Failed to create geofence:', error.message);
    }
}

5. Cache Geofence Data

const geofenceCache = new Map();

async function getCachedGeofence(geofenceId) {
    if (geofenceCache.has(geofenceId)) {
        return geofenceCache.get(geofenceId);
    }
    
    const geofence = await client.geofencing.getById(geofenceId);
    geofenceCache.set(geofenceId, geofence);
    
    // Cache for 5 minutes
    setTimeout(() => geofenceCache.delete(geofenceId), 300000);
    
    return geofence;
}

Limitations

  • Maximum 100 geofences per project (varies by plan)
  • Polygon geofences: Maximum 100 vertices
  • Circle geofences: Maximum radius 50 km
  • Rate limits apply based on your API plan

Next Steps

On this page