How to Integrate GeoAgent and Geocoding in GeoLibre: AI-Assisted Mapping Features
Integrate AI-assisted GeoAgent and geocoding features in GeoLibre by registering the maplibre-geoagent and maplibre-reverse-geocode plugins, configuring provider credentials via environment variables, and using the core geocodeForward and geocodeReverse APIs.
GeoLibre provides a modular plugin architecture that enables AI-assisted capabilities through GeoLibrePlugin implementations. The GeoAgent plugin combines Google Earth Engine with LLM-powered tools, while the geocoding system offers both forward and reverse address lookup. Both features build on the core geocoding service in @geolibre/core and mount as MapLibre controls via @geolibre/plugins.
GeoAgent Plugin Architecture
The GeoAgent plugin (packages/plugins/src/plugins/maplibre-geoagent.ts) wraps the maplibre-gl-geoagent control and manages three critical functions: dynamic control loading, Earth Engine authentication, and overlay synchronization.
Control Loading and Initialization
The plugin lazily imports the GeoAgent control through loadGeoAgentControl() and instantiates it with options defined in GEOAGENT_OPTIONS. These options include OAuth client ID, Earth Engine project ID, and default visualization parameters.
Earth Engine Authentication
Authentication flows through packages/plugins/src/plugins/earth-engine-auth.ts. The plugin calls authenticateEarthEngine() to obtain an access token, then applies it via applyEarthEngineAccessToken() and updates the control through updateEarthEngineOptions().
Overlay Synchronization
After any GeoAgent tool executes, the plugin invokes syncGeoAgentOverlaysToStore() from geoagent-layer-sync.ts. This ensures Earth Engine layers appear in GeoLibre's layer panel and remain synchronized with the core store.
Geocoding Core Implementation
The geocoding system in packages/core/src/geocoding.ts provides provider-agnostic address resolution with built-in throttling and request management.
Provider Registry
The GEOCODING_PROVIDERS registry supports five backends:
- Nominatim (OpenStreetMap) – default, requires
User-Agentheader - Pelias – configurable endpoint
- ArcGIS – commercial service
- Mapbox – requires API key
- Google – requires API key
Each provider implements four methods: buildForwardUrl, parseForward, buildReverseUrl, and parseReverse.
Request Throttling and Rate Limits
The core enforces Nominatim's public policy through:
shouldThrottle()– checksgeocoderMinIntervalMs(1000ms default)rowCap– limits result sets- Request deduplication via internal state
Fetch Override for Desktop Builds
The setGeocodingFetch() function allows the Tauri desktop shell to inject a native HTTP implementation that bypasses CORS and sets required headers like User-Agent. This is called from apps/geolibre-desktop/src/lib/geocoding-fetch.ts at application startup.
Reverse Geocoding Plugin
The reverse geocode plugin (packages/plugins/src/plugins/maplibre-reverse-geocode.ts) provides click-to-address functionality:
- Registers a map click handler that calls
geocodeReverse()from the core - Lazily imports
Popupfrommaplibre-glto display results - Includes a copy-to-clipboard button in the popup DOM
- Uses
restoreReverseGeocode()to rebind handlers after map re-initialization
Configuration and Setup
Plugin Registration
Plugins load automatically via usePlugins.ts in the desktop application. Both GeoAgent and reverse geocode plugins export a GeoLibrePlugin interface:
// Normally handled automatically by usePlugins.ts
import { maplibreGeoAgentPlugin } from '@geolibre/plugins';
import { maplibreReverseGeocodePlugin } from '@geolibre/plugins';
app.addPlugin(maplibreGeoAgentPlugin.id);
app.addPlugin(maplibreReverseGeocodePlugin.id);
Environment Variable Configuration
Create a .env file or set variables through the desktop UI:
VITE_GEOCODER_PROVIDER=nominatim # nominatim | pelias | arcgis | mapbox | google
VITE_GEOCODER_EMAIL=you@example.com # Required for public Nominatim
VITE_GEOCODER_API_KEY=YOUR_KEY # Required for Mapbox, Google, ArcGIS
VITE_GEOCODER_ENDPOINT=https://custom/api/search
VITE_GEOCODER_REVERSE_ENDPOINT=https://custom/api/reverse
The core reads these through getGeocoderConfig() at runtime.
Code Examples
Activating GeoAgent Programmatically
import { app } from '@geolibre/app';
// Enable the plugin from custom UI (e.g., toolbar button)
await app.activatePlugin('maplibre-gl-geoagent');
// The control mounts automatically and handles Earth Engine auth
Forward Geocoding in Custom Tools
import { geocodeForward, getGeocoderConfig } from '@geolibre/core';
async function locateFacility(address: string) {
const config = getGeocoderConfig();
const matches = await geocodeForward(address, {
config,
limit: 5,
bbox: [-125, 25, -66, 49] // Optional US bounding box bias
});
return matches.map(m => ({
lat: m.lat,
lon: m.lon,
name: m.displayName,
confidence: m.score
}));
}
Manual Reverse Geocoding
import { geocodeReverse } from '@geolibre/core';
async function getAddressFromCoordinates(lng: number, lat: number) {
const result = await geocodeReverse(lng, lat, {
zoom: 18 // Address detail level (1-18)
});
if (!result) {
throw new Error('No address found at this location');
}
return {
fullAddress: result.displayName,
country: result.address?.country,
city: result.address?.city || result.address?.town
};
}
Desktop Fetch Override
import { setGeocodingFetch } from '@geolibre/core';
import { fetch as tauriFetch } from '@tauri-apps/api/http';
// Must be called before any geocoding operations
setGeocodingFetch(async (url, options) => {
const response = await tauriFetch(url, {
method: options?.method || 'GET',
headers: {
'User-Agent': 'GeoLibre/1.0 (https://geolibre.org)',
...options?.headers
}
});
return new Response(JSON.stringify(response.data), {
status: response.status,
headers: response.headers
});
});
Key Implementation Files
| Path | Purpose |
|---|---|
packages/plugins/src/plugins/maplibre-geoagent.ts |
GeoAgent plugin: control loading, Earth Engine auth, overlay sync |
packages/plugins/src/plugins/geoagent-layer-sync.ts |
Store synchronization for GeoAgent overlays |
packages/plugins/src/plugins/earth-engine-auth.ts |
OAuth and token management for Earth Engine |
packages/core/src/geocoding.ts |
Core geocoding: providers, throttling, forward/reverse APIs |
packages/plugins/src/plugins/maplibre-reverse-geocode.ts |
Click handler and popup UI for reverse geocoding |
apps/geolibre-desktop/src/lib/geocoding-fetch.ts |
Tauri HTTP wrapper for desktop builds |
Summary
- GeoAgent integrates Earth Engine + LLM tools through a plugin that handles authentication, control mounting, and layer synchronization.
- Geocoding supports five providers with configurable endpoints, rate limiting, and a fetch override mechanism for desktop environments.
- Both features follow GeoLibre's plugin pattern: core logic in
@geolibre/core, UI controls in@geolibre/plugins, and platform-specific adaptations in the desktop shell. - Configuration uses
VITE_GEOCODER_*environment variables read viagetGeocoderConfig(). - Desktop builds must call
setGeocodingFetch()to inject Tauri's HTTP client and satisfy provider header requirements.
Frequently Asked Questions
How do I enable GeoAgent in a custom GeoLibre build?
Import maplibreGeoAgentPlugin from @geolibre/plugins and add it to your plugins array in usePlugins.ts or call app.addPlugin(maplibreGeoAgentPlugin.id) programmatically. Activation occurs automatically from the Plugins menu or via app.activatePlugin().
Why is Nominatim geocoding failing with 403 errors?
Public Nominatim requires a valid User-Agent header and prefers an identifying email. In desktop builds, call setGeocodingFetch() with a custom fetch that includes these headers. Web builds must ensure the hosting domain complies with Nominatim's Usage Policy.
Can I use a private geocoding endpoint with GeoLibre?
Yes. Set VITE_GEOCODER_ENDPOINT and VITE_GEOCODER_REVERSE_ENDPOINT to your custom URLs, and select a compatible provider configuration. The buildForwardUrl and buildReverseUrl methods in your provider will use these endpoints instead of defaults.
How does GeoAgent synchronize Earth Engine layers with the layer panel?
After each tool execution, syncGeoAgentOverlaysToStore() in geoagent-layer-sync.ts reads the GeoAgent control's overlay state and dispatches updates to the core store. This mirrors the pattern used by other data sources to maintain reactive UI consistency.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →