|
3 | 3 | ## Interface |
4 | 4 |
|
5 | 5 | ```typescript |
6 | | -import type { FeatureCollection } from "geojson"; |
| 6 | +import type { Feature, FeatureCollection, Geometry } from "geojson"; |
7 | 7 | import type { IControl } from "maplibre-gl"; |
8 | 8 |
|
9 | 9 | export type GeoLibreMapControlPosition = |
@@ -55,13 +55,34 @@ export interface GeoLibreDeckGL { |
55 | 55 | mapbox: typeof import("@deck.gl/mapbox"); |
56 | 56 | } |
57 | 57 |
|
| 58 | +export interface GeoLibreLayerSummary { |
| 59 | + id: string; |
| 60 | + name: string; |
| 61 | + type: string; |
| 62 | + visible: boolean; |
| 63 | + opacity: number; |
| 64 | +} |
| 65 | + |
| 66 | +export interface GeoLibreSelection { |
| 67 | + layerId: string | null; |
| 68 | + features: Feature<Geometry | null>[]; |
| 69 | +} |
| 70 | + |
58 | 71 | export interface GeoLibreAppAPI { |
59 | 72 | setBasemap: (styleUrl: string) => void; |
60 | 73 | addGeoJsonLayer: ( |
61 | 74 | name: string, |
62 | 75 | data: FeatureCollection, |
63 | 76 | sourcePath?: string, |
64 | 77 | ) => string; |
| 78 | + listLayers?: () => GeoLibreLayerSummary[]; |
| 79 | + getLayerFeatures?: (layerId: string) => Feature<Geometry | null>[]; |
| 80 | + getSelectedFeatures?: () => Feature<Geometry | null>[]; |
| 81 | + getSelectedLayerId?: () => string | null; |
| 82 | + getDrawnFeatures?: () => Feature<Geometry | null>[]; |
| 83 | + onSelectionChange?: ( |
| 84 | + callback: (selection: GeoLibreSelection) => void, |
| 85 | + ) => () => void; |
65 | 86 | // Native raster/tile layers (see "Raster and tile layers" below). Each |
66 | 87 | // returns the new layer's id and the layer appears in the Layers panel and |
67 | 88 | // persists with the project, like addGeoJsonLayer does for vector data. |
@@ -416,6 +437,48 @@ https://web.geolibre.app/?url=https://example.com/project.geolibre.json&exampleG |
416 | 437 |
|
417 | 438 | A URL parameter activates only an already-registered (installed) plugin that owns it; it never loads a plugin from the URL. For external plugins, include the plugin manifest URL in the project `plugins` state (so the plugin is registered) before relying on its URL handler — the matching parameter then activates and dispatches it even if it is not in the active set. |
418 | 439 |
|
| 440 | +## Read-only layer and feature queries |
| 441 | + |
| 442 | +External plugins can inspect the current layer list, a layer's GeoJSON features, |
| 443 | +the current feature selection, and features in GeoEditor's Sketches layers. The |
| 444 | +methods are optional so the same plugin remains compatible with older hosts. |
| 445 | + |
| 446 | +```typescript |
| 447 | +const layers = app.listLayers?.() ?? []; |
| 448 | +const selectedLayerId = app.getSelectedLayerId?.() ?? null; |
| 449 | +const selectedFeatures = app.getSelectedFeatures?.() ?? []; |
| 450 | + |
| 451 | +if (selectedLayerId && app.getLayerFeatures) { |
| 452 | + const layerFeatures = app.getLayerFeatures(selectedLayerId); |
| 453 | + console.log(layers, layerFeatures, selectedFeatures); |
| 454 | +} |
| 455 | + |
| 456 | +const drawnFeatures = app.getDrawnFeatures?.() ?? []; |
| 457 | +``` |
| 458 | + |
| 459 | +`getSelectedFeatures` returns every selected feature in the selected layer, not |
| 460 | +only the most recently selected feature. Features without a GeoJSON `id` are |
| 461 | +matched using their zero-based array index converted to a string. An empty |
| 462 | +selection returns an empty array. `getLayerFeatures` throws when the layer id is |
| 463 | +unknown and returns an empty array for a layer that has no GeoJSON features. |
| 464 | + |
| 465 | +Selection subscriptions fire after the selected layer or selected feature-id |
| 466 | +array changes. Keep and call the returned unsubscribe function during plugin |
| 467 | +deactivation: |
| 468 | + |
| 469 | +```typescript |
| 470 | +const unsubscribe = app.onSelectionChange?.(({ layerId, features }) => { |
| 471 | + console.log(layerId, features); |
| 472 | +}); |
| 473 | + |
| 474 | +// In deactivate or another cleanup path: |
| 475 | +unsubscribe?.(); |
| 476 | +``` |
| 477 | + |
| 478 | +These methods are a read-only query surface: calling them does not change the |
| 479 | +GeoLibre store. Plugins must also treat returned GeoJSON features as read-only |
| 480 | +and use host APIs such as `addGeoJsonLayer` when they need to add data. |
| 481 | + |
419 | 482 | ## Raster and tile layers |
420 | 483 |
|
421 | 484 | `addGeoJsonLayer` registers vector data as a native layer. For raster and tile data there are three matching helpers — `addTileLayer` (XYZ), `addWmtsLayer` (WMTS), and `addWmsLayer` (WMS). Each returns the new layer's id, and the layer appears in the Layers panel with full opacity, reorder, and styling support and persists with the project, so a plugin no longer has to call `getMap().addSource()/addLayer()` directly (which leaves the layer invisible to GeoLibre's layer store). |
|
0 commit comments