oglap-ggp-node
v1.0.3
Published
Permettre aux développeurs d'installer rapidement le SDK et ses dépendances pour commencer à l'utiliser dans leurs projets.
Downloads
94
Maintainers
Readme
oglap-ggp-node-js
Implémentation Node.js du protocole OGLAP (Offline Grid Location Addressing Protocol) — un système d'adressage déterministe basé sur une grille, conçu pour les régions où les adresses postales formelles sont inexistantes ou peu fiables.
OGLAP génère des codes LAP compacts et lisibles (ex. GN-CON-QYTC-B0B1-2282) qui identifient de façon unique n'importe quelle coordonnée à l'intérieur d'un pays configuré, hors ligne et sans API externe.
Fonctionnalités
- Coordonnées → code LAP — encoder toute position GPS en adresse LAP structurée
- Code LAP → coordonnées — décoder un code LAP vers son centre géographique
- Geocodage inversé — trouver la région administrative, zone et lieu contenant une coordonnée
- Parsing & validation de code LAP — analyser des codes partiels ou complets, valider le format et le contenu
- Boîte englobante et centroïde — calculer bbox et centre à partir de géométries GeoJSON
- Entièrement hors ligne — aucune connexion requise une fois les données chargées
Format du code LAP
Un code LAP encode une localisation à quatre niveaux hiérarchiques :
Grille locale (5 segments)
GN - CON - QYTC - B0B1 - 2282
│ │ │ │ └─ Microspot — 4 chiffres, offset métrique (XX = est, YY = nord)
│ │ │ └─────── Macrobloc — 4 chars [A-J][0-9][A-J][0-9], blocs ~100 m dans la zone
│ │ └────────────── Zone — 4 chars, indiquant la localite administrative immediate de niveau 8 et plus (example - QYTC pour Yattaya - Fossedè)
│ └───────────────────── Région — 3 chars, code de la localite administrative de niveau 4 ou 6 immediate (example - CON pour Conakry)
└──────────────────────────── Pays — code ISO alpha-2 du pays (example - gn pour Guinee)Grille nationale (4 segments)
Utilisée quand une coordonnée se situe en dehors des limites administratives de niveau 8 et au-dessus :
GN - NZE - AABCDE - 4250
│ │ │ └─ Microspot — 4 chiffres
│ │ └────────── Macrobloc — 6 lettres, grille kilométrique nationale
│ └──────────────── Région — 3 chars, code de la localite administrative de niveau 4 ou 6 immediate (example - NZE pour Nzérékoré)
└─────────────────────── Pays — code ISO alpha-2 du pays (example - gn pour Guinee)Démarrage
1. Ajouter la dépendance
npm install oglap-ggp-node-js2. Préparer les données
Le package nécessite trois fichiers JSON :
| Fichier | Description |
|---|---|
| {country_code}_oglap_country_profile.json | Paramètres de grille, codes admin, règles de nommage |
| {country_code}_localities_naming.json | Géométries GeoJSON des lieux (régions, zones, localités) |
| {country_code}_full.json | Correspondances place-ID → code OGLAP |
3. Initialiser avant toute utilisation
Appeler initOglap une seule fois au démarrage de l'application, avant toute autre fonction :
Mode téléchargement (recommandé) — les données sont téléchargées et mises en cache localement :
import { initOglap } from 'oglap-ggp-node-js';
const report = await initOglap({
version: 'latest',
dataDir: 'oglap-data', // dossier de cache local
forceDownload: false,
onProgress({ label, status, percent, step, totalSteps }) {
if (status === 'downloading') process.stdout.write(`\r↓ [${step}/${totalSteps}] ${label}: ${percent}%`);
if (status === 'cached') console.log(`⚡ [${step}/${totalSteps}] ${label}: depuis le cache`);
if (status === 'done') console.log(`\r✓ [${step}/${totalSteps}] ${label}: terminé`);
if (status === 'error') console.log(`✗ [${step}/${totalSteps}] ${label}: erreur`);
}
});
if (!report.ok) throw new Error(report.error);Utilisation
Encoder des coordonnées en code LAP
import { coordinatesToLap } from 'oglap-ggp-node-js';
const result = coordinatesToLap(9.5370, -13.6773); // lat, lon — Conakry, Guinée
console.log(result.lapCode); // GN-CON-QYTC-B0B1-2282
console.log(result.humanAddress); // B0B1-2282, Yattaya Fossedè, Conakry, Guinée
console.log(result.admin_level_2); // CON (code de région)
console.log(result.admin_level_3); // QYTC (code de zone)
console.log(result.macroblock); // B0B1
console.log(result.microspot); // 2282
console.log(result.isNationalGrid); // false
console.log(result.originLat); // latitude d'origine de la bbox
console.log(result.originLon); // longitude d'origine de la bboxRetourne null si les coordonnées sont hors du territoire.
Décoder un code LAP en coordonnées
import { lapToCoordinates } from 'oglap-ggp-node-js';
const coords = lapToCoordinates('GN-CON-QYTC-B0B1-2282');
if (coords) {
console.log(`lat: ${coords.lat}, lon: ${coords.lon}`);
// lat: 9.5370..., lon: -13.6773...
}
// Le préfixe pays est optionnel
const coords2 = lapToCoordinates('GN-CON-QYTC-B0B1-2282');Parser et valider un code LAP
import { validateLapCode, parseLapCode } from 'oglap-ggp-node-js';
// Valider — retourne un message d'erreur, ou null si valide
const error = validateLapCode('GN-CON-QYTC-B0B1-2282');
if (error) {
console.log('Invalide :', error);
} else {
console.log('Code valide');
}
// Parser en composants
const parsed = parseLapCode('GN-CON-QYTC-B0B1-2282');
if (parsed) {
console.log(parsed.admin_level_2_Iso); // code ISO du pays : GN
console.log(parsed.admin_level_3_code); // code de la localite administrative de niveau 4 ou 6 immediate : CON
console.log(parsed.admin_level_4_code); // code de la localite administrative de niveau 8 et plus : QYTC
console.log(parsed.macroblock); // B0B1 macrobloc ~100m x 100m dans la zone
console.log(parsed.microspot); // 2282 microspot ~1m x 1m dans la zone
console.log(parsed.isNationalGrid); // false
}
// Les codes partiels sont aussi supportés
parseLapCode('GN-CON-QYTC'); // région + zone seulement
parseLapCode('QYTC'); // zone seulementRésoudre un code LAP vers un lieu
import { getPlaceByLapCode } from 'oglap-ggp-node-js';
const resolved = getPlaceByLapCode('GN-CON-QYTC-B0B1-2282');
if (resolved) {
console.log(resolved.originLat); // latitude d'origine de la bbox
console.log(resolved.originLon); // longitude d'origine de la bbox
if (resolved.place) {
const addr = resolved.place.address;
const name = addr?.village ?? addr?.town ?? addr?.city ?? resolved.place.display_name;
console.log(name); // nom du lieu lisible
}
// Accéder aux composants parsés
console.log(resolved.parsed.macroblock); // B0B1
console.log(resolved.parsed.microspot); // 2282
}Boîte englobante et centroïde
import { bboxFromGeometry, centroidFromBbox } from 'oglap-ggp-node-js';
const geometry = {
type: 'Polygon',
coordinates: [[
[-13.70, 9.50],
[-13.65, 9.50],
[-13.65, 9.55],
[-13.70, 9.55],
[-13.70, 9.50],
]]
};
const bbox = bboxFromGeometry(geometry);
// [minLat, maxLat, minLon, maxLon]
if (bbox) {
const center = centroidFromBbox(bbox);
// [lat, lon] du point central de la bbox
console.log(`Centre : ${center[0]}, ${center[1]}`);
}Accéder aux métadonnées du pays
import { getCountryCode, getCountrySW, getOglapPrefectures } from 'oglap-ggp-node-js';
console.log(getCountryCode()); // "GN"
console.log(getCountrySW()); // [lat, lon] du coin sud-ouest
const prefectures = getOglapPrefectures();
// { [isoCode]: prefectureOglapCode, ... }Modèles de données
Résultat de coordinatesToLap
| Champ | Type | Description |
|---|---|---|
| lapCode | string | Code LAP complet, ex. GN-CON-QYTC-B0B1-2282 |
| country | string | Code pays, ex. GN |
| admin_level_2 | string | Code de région, ex. CON |
| admin_level_3 | string\|null | Code de zone, ex. QYTC |
| macroblock | string | Composant macrobloc |
| microspot | string | Composant microspot |
| isNationalGrid | boolean | true si grille nationale utilisée |
| displayName | string | Nom du lieu issu du geocodage inversé |
| humanAddress | string | Adresse complète lisible |
| address | object | Composants d'adresse structurés |
| originLat | number | Latitude d'origine de la bbox |
| originLon | number | Longitude d'origine de la bbox |
| pcode | string[] | P-codes UNOCHA pour la localisation |
Résultat de parseLapCode
| Champ | Type | Description |
|---|---|---|
| admin_level_2_Iso | string\|undefined | Code ISO de la région |
| admin_level_3_code | string\|undefined | Code de zone |
| macroblock | string\|undefined | Composant macrobloc |
| microspot | string\|undefined | Composant microspot |
| isNationalGrid | boolean | true si grille nationale |
Résultat de getPlaceByLapCode
| Champ | Type | Description |
|---|---|---|
| place | object\|null | Données OSM du lieu |
| parsed | object | Composants LAP parsés |
| originLat | number\|undefined | Latitude d'origine de la bbox |
| originLon | number\|undefined | Longitude d'origine de la bbox |
Rapport de initOglap
| Champ | Type | Description |
|---|---|---|
| ok | boolean | Initialisation réussie |
| countryCode | string\|null | Ex. GN |
| countryName | string\|null | Ex. Guinée |
| bounds | number[][]\|null | [[swLat, swLon], [neLat, neLon]] |
| checks | Array | Résultats de validation (pass, warn, fail) |
| error | string\|null | Message d'erreur si !ok |
| dataDir | string\|undefined | Dossier de cache local |
| dataLoaded | object\|undefined | Résultat du chargement des lieux |
Exemple complet de bout en bout
import {
initOglap,
checkOglap,
coordinatesToLap,
lapToCoordinates,
getPlaceByLapCode,
validateLapCode,
parseLapCode,
} from 'oglap-ggp-node-js';
class LocationService {
static #initialized = false;
static async init() {
if (this.#initialized) return;
const report = await initOglap({
onProgress({ label, status, percent, step, totalSteps }) {
if (status === 'downloading') process.stdout.write(`\r↓ [${step}/${totalSteps}] ${label}: ${percent}%`);
if (status === 'cached') console.log(`⚡ [${step}/${totalSteps}] ${label}: depuis le cache`);
if (status === 'done') console.log(`\r✓ [${step}/${totalSteps}] ${label}: terminé`);
if (status === 'error') console.log(`✗ [${step}/${totalSteps}] ${label}: erreur`);
}
});
if (!report.ok) throw new Error(`Initialisation OGLAP échouée : ${report.error}`);
this.#initialized = true;
}
/** Encoder la position GPS de l'utilisateur */
static encodePosition(lat, lon) {
const result = coordinatesToLap(lat, lon);
return result?.lapCode ?? null;
}
/** Partager une localisation : retourne le code LAP et l'adresse lisible */
static shareLocation(lat, lon) {
const result = coordinatesToLap(lat, lon);
if (!result) return null;
return {
code: result.lapCode,
label: result.humanAddress,
};
}
/** Naviguer vers un code LAP en le convertissant en coordonnées */
static decodeToCoords(lapCode) {
return lapToCoordinates(lapCode); // { lat, lon } ou null
}
/** Valider la saisie d'un code LAP par l'utilisateur */
static validateInput(input) {
return validateLapCode(input); // null = valide, string = message d'erreur
}
/** Résoudre un code LAP vers les détails du lieu */
static resolvePlace(lapCode) {
const resolved = getPlaceByLapCode(lapCode);
if (!resolved?.place) return null;
const addr = resolved.place.address ?? {};
return {
name: addr.village ?? addr.town ?? addr.city ?? resolved.place.display_name,
adminCode: resolved.parsed.admin_level_3_code,
originLat: resolved.originLat,
originLon: resolved.originLon,
};
}
}
// Utilisation
await LocationService.init();
// Encoder
const code = LocationService.encodePosition(9.660147, -13.588009);
console.log(code); // GN-CON-QYTC-B0B1-2282
// Décoder
const coords = LocationService.decodeToCoords(code);
console.log(coords); // { lat: 9.660147, lon: -13.588009 }
// Partager
const share = LocationService.shareLocation(9.660147, -13.588009);
console.log(share.label); // B0B1-2282, Yattaya Fossedè, Conakry, Guinée
// Valider la saisie utilisateur
const err = LocationService.validateInput('GN-CON-QYTC-B0B1-2282');
console.log(err); // null (valide)
// Résoudre un lieu
const place = LocationService.resolvePlace('GN-CON-QYTC-B0B1-2282');
console.log(place.display_name); // Yattaya Fossedè, Ratoma, Conakry, GuinéeExécuter les tests
node test.jsInformations complémentaires
- Protocole : OGLAP est conçu pour la Guinée (
GN) mais configurable pour tout pays via le fichier profil JSON. - Offline-first : tout l'encodage et décodage est effectué localement avec les données chargées — aucun réseau requis.
- Déterministe : les mêmes coordonnées produisent toujours le même code LAP, à données identiques.
- Bugs : signaler les problèmes dans le dépôt principal Kiraa.
