Google Maps–like JavaScript SDK for Nepal only. Tiles show route names with faded buildings; data is cached on device (IndexedDB) and server.
node server.js) so /tiles/ and /api/* are available.GOOGLE_PLACES_API_KEY or GOOGLE_MAPS_API_KEY in the environment.<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<div id="map" style="height: 400px;"></div>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<script src="https://your-server.com/nepal-map-sdk.js"></script>
<script>
var map = new NepalMap('map', { zoom: 10, center: [27.7, 85.32] });
map.loadPlaces();
</script>
When your site is not on the same origin as the map server, set baseUrl:
var map = new NepalMap('map', {
baseUrl: 'https://your-maps-server.com',
zoom: 10,
center: [27.7, 85.32]
});
new NepalMap(containerId, options)
baseUrl, zoom, center, minZoom/maxZoom, routeColor/routeWeight.[{ name, lat, lng, address }].{ coords, totalDistance?, totalDuration?, legs? }.opts: popup, title, icon.Use the route API from PHP for server-side only route calculation (no map; get distance, time, legs). All points must be within Nepal. The backend caches results and returns full route on first request.
Base URL: your NepalMap server (e.g. http://localhost:3000 or https://maps.example.com).
<?php
/**
* Nepal bounds (for validation). [south, west, north, east]
*/
function nepal_map_bounds() {
return [26.35, 80.06, 30.45, 88.2];
}
/**
* Check if a point is inside Nepal.
*/
function nepal_map_point_in_nepal($lat, $lng) {
list($s, $w, $n, $e) = nepal_map_bounds();
return $lat >= $s && $lat <= $n && $lng >= $w && $lng <= $e;
}
/**
* Get driving route between two or more points (server-side only).
* GET /api/route. All points must be in Nepal.
*
* @param string $baseUrl NepalMap server base URL
* @param array $points Array of [lat, lng] or ['lat' => x, 'lng' => y]
* @return array|null route (coords), totalDistance (m), totalDuration (s), legs, or null
*/
function nepal_map_route($baseUrl, array $points) {
if (count($points) < 2) return null;
$flat = array_map(function ($p) {
$lat = isset($p['lat']) ? $p['lat'] : $p[0];
$lng = isset($p['lng']) ? $p['lng'] : $p[1];
return $lat . ',' . $lng;
}, $points);
$query = 'points=' . rawurlencode(implode(';', $flat));
$url = rtrim($baseUrl, '/') . '/api/route?' . $query;
$ctx = stream_context_create(['http' => ['timeout' => 15]]);
$raw = @file_get_contents($url, false, $ctx);
if ($raw === false) return null;
$data = json_decode($raw, true);
return is_array($data) ? $data : null;
}
/**
* Get route from start to end (convenience).
*/
function nepal_map_route_two($baseUrl, $startLat, $startLng, $endLat, $endLng) {
return nepal_map_route($baseUrl, [[$startLat, $startLng], [$endLat, $endLng]]);
}
/**
* Format route result for display (total + legs).
* @return array total_km, total_duration_min, legs (array of km, min)
*/
function nepal_map_route_summary(array $result) {
$totalKm = isset($result['totalDistance']) ? round($result['totalDistance'] / 1000, 2) : null;
$totalMin = isset($result['totalDuration']) ? round($result['totalDuration'] / 60, 1) : null;
$legs = [];
if (!empty($result['legs'])) {
foreach ($result['legs'] as $leg) {
$legs[] = [
'km' => round(($leg['distance'] ?? 0) / 1000, 2),
'min' => round(($leg['duration'] ?? 0) / 60, 1)
];
}
}
return ['total_km' => $totalKm, 'total_duration_min' => $totalMin, 'legs' => $legs];
}
$baseUrl = 'http://localhost:3000';
$result = nepal_map_route_two($baseUrl, 27.7172, 85.324, 28.2096, 83.9856);
if ($result && !empty($result['route'])) {
$summary = nepal_map_route_summary($result);
echo "Total: " . $summary['total_km'] . " km, " . $summary['total_duration_min'] . " min\n";
foreach ($summary['legs'] as $i => $leg) {
echo "Leg " . ($i + 1) . ": " . $leg['km'] . " km, " . $leg['min'] . " min\n";
}
}
GET /tiles/:z/:x/:y.png — Nepal only, cached.GET /api/places?bounds=... — Nepal-only, cached.GET /api/suggest?query=... — Google when key set; else Nominatim; cached. Format: { name, address, lat, lng }.GET /api/reverse?lat=...&lng=... — Lat/lng → place name & address (same format as suggest); cached and synced to suggest.GET /api/route?start=lat,lng&end=lat,lng or ?points=... — All points in Nepal; cached. Response: route, totalDistance, totalDuration, legs. On cache miss the server fetches OSRM and returns the full response.GET /api/route/simple?start=lat,lng&end=lat,lng or ?points=... — Same params. Returns only totalDistance (m), totalDuration (s), polyline (encoded). Uses cache when available; otherwise fetches OSRM so it always returns even when not cached.GET /api/config — Bounds and tile URL.Cache layout: cache/tiles/, cache/suggest/, cache/place_details/, cache/places.json, cache/routes.json.
Open demo.html (e.g. http://localhost:3000/demo.html) to try the SDK with search and caching.