geoai 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.0.5] - 2026-07-15
11
+
12
+ ### Added
13
+ - WMS map provider with OGC GetMap support (EPSG:3857 bbox, WMS 1.1.1 / 1.3.0)
14
+ - `examples/06-wms-quickstart` — NRW orthophotos (`nw_dop_rgb`), draw-to-detect, NRW geocoder
15
+ - Interactive TMS and WMS providers in `live-examples-nextjs` task demos
16
+ - WMS documentation (`wms.mdx`), map-providers table update, and 17 WMS tests (including pipeline inference)
17
+ - Project roadmap (`_docs4devs/ROADMAP.md`) for use-case guides and quantization pipeline backlog
18
+
19
+ ### Changed
20
+ - `live-examples-nextjs` pins `geoai` to local `build/` for WMS/TMS provider development
21
+
10
22
  ## [1.0.4] - 2026-07-11
11
23
 
12
24
  ### Added
package/README.md CHANGED
@@ -40,12 +40,12 @@ You can also use GeoAI directly in the browser via CDN:
40
40
 
41
41
  #### Unpkg CDN
42
42
  ```html
43
- <script src="https://unpkg.com/geoai@1.0.3/geoai.js"></script>
43
+ <script src="https://unpkg.com/geoai@1.0.5/geoai.js"></script>
44
44
  ```
45
45
 
46
46
  #### jsDelivr CDN
47
47
  ```html
48
- <script src="https://cdn.jsdelivr.net/npm/geoai@1.0.3/geoai.min.js"></script>
48
+ <script src="https://cdn.jsdelivr.net/npm/geoai@1.0.5/geoai.min.js"></script>
49
49
  ```
50
50
 
51
51
  When using CDN, the library is available globally as `geoai`.
@@ -235,6 +235,7 @@ const pipeline = await geoai.pipeline([{ task: "object-detection" }], {
235
235
 
236
236
  - **Documentation**: [docs.geobase.app/geoai](https://docs.geobase.app/geoai) - Comprehensive documentation, examples, and API reference
237
237
  - **Live Examples**: [docs.geobase.app/geoai-live](https://docs.geobase.app/geoai-live) - Interactive examples and demos
238
+ - **Roadmap**: [_docs4devs/ROADMAP.md](_docs4devs/ROADMAP.md) - Planned docs, quantization pipeline, and related backlog
238
239
  - **Community**: [GitHub Discussions](https://github.com/decision-labs/geoai.js/discussions) - Ask questions, share ideas, and connect with other developers
239
240
  - **Code**: [GitHub Repository](https://github.com/decision-labs/geoai.js) - Source code and contributions
240
241
  - **Issues**: [GitHub Issues](https://github.com/decision-labs/geoai.js/issues) - Report bugs and request features
package/geoai.js CHANGED
@@ -390,7 +390,7 @@ const postProcessYoloOutput = (model_outputs, pixel_values, rawImage, id2label)
390
390
  return model_output;
391
391
  };
392
392
  const parametersChanged = (instance, model_id, providerParams, modelParams) => {
393
- var _a, _b, _c, _d, _e, _f, _g, _h;
393
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
394
394
  if (instance.model_id !== model_id) {
395
395
  return true;
396
396
  }
@@ -419,6 +419,12 @@ const parametersChanged = (instance, model_id, providerParams, modelParams) => {
419
419
  if (((_h = instance.providerParams) == null ? void 0 : _h.baseUrl) !== (providerParams == null ? void 0 : providerParams.baseUrl)) {
420
420
  return true;
421
421
  }
422
+ break;
423
+ case "wms":
424
+ if (((_i = instance.providerParams) == null ? void 0 : _i.baseUrl) !== (providerParams == null ? void 0 : providerParams.baseUrl) || ((_j = instance.providerParams) == null ? void 0 : _j.layers) !== (providerParams == null ? void 0 : providerParams.layers) || ((_k = instance.providerParams) == null ? void 0 : _k.version) !== (providerParams == null ? void 0 : providerParams.version) || ((_l = instance.providerParams) == null ? void 0 : _l.crs) !== (providerParams == null ? void 0 : providerParams.crs)) {
425
+ return true;
426
+ }
427
+ break;
422
428
  }
423
429
  if (modelParams) {
424
430
  const instanceModelParams = instance.modelParams || {};
@@ -1283,6 +1289,97 @@ class Tms extends MapSource {
1283
1289
  return url;
1284
1290
  }
1285
1291
  }
1292
+ function formatWmsBbox(bbox2, crs, version) {
1293
+ const [minX, minY, maxX, maxY] = bbox2;
1294
+ if (version === "1.3.0" && crs === "EPSG:4326") {
1295
+ return `${minY},${minX},${maxY},${maxX}`;
1296
+ }
1297
+ return `${minX},${minY},${maxX},${maxY}`;
1298
+ }
1299
+ function getTileBbox(tileCoords, crs, tileSize) {
1300
+ const [x, y, z] = tileCoords;
1301
+ if (crs === "EPSG:3857") {
1302
+ const toMeters = pixelsToMeters;
1303
+ const min = toMeters([x * tileSize, y * tileSize, z], tileSize);
1304
+ const max = toMeters([(x + 1) * tileSize, (y + 1) * tileSize, z], tileSize);
1305
+ return [
1306
+ Math.min(min[0], max[0]),
1307
+ Math.min(min[1], max[1]),
1308
+ Math.max(min[0], max[0]),
1309
+ Math.max(min[1], max[1])
1310
+ ];
1311
+ }
1312
+ return tileToBBox(tileCoords);
1313
+ }
1314
+ function buildWmsGetMapUrl(config, tileCoords) {
1315
+ const version = config.version ?? "1.1.1";
1316
+ const crs = config.crs ?? "EPSG:3857";
1317
+ const tileSize = config.tileSize ?? 256;
1318
+ const bbox2 = getTileBbox(tileCoords, crs, tileSize);
1319
+ const bboxParam = formatWmsBbox(bbox2, crs, version);
1320
+ const params = {
1321
+ SERVICE: "WMS",
1322
+ REQUEST: "GetMap",
1323
+ VERSION: version,
1324
+ LAYERS: config.layers,
1325
+ STYLES: config.styles ?? "",
1326
+ FORMAT: config.format ?? "image/png",
1327
+ WIDTH: tileSize.toString(),
1328
+ HEIGHT: tileSize.toString(),
1329
+ BBOX: bboxParam,
1330
+ ...version === "1.3.0" ? { CRS: crs } : { SRS: crs },
1331
+ ...config.transparent ? { TRANSPARENT: "TRUE" } : {},
1332
+ ...config.extraParams ?? {}
1333
+ };
1334
+ const url = new URL(config.baseUrl);
1335
+ for (const [key, value] of Object.entries(params)) {
1336
+ url.searchParams.set(key, value);
1337
+ }
1338
+ return url.toString();
1339
+ }
1340
+ class Wms extends MapSource {
1341
+ constructor(config) {
1342
+ super();
1343
+ __publicField(this, "baseUrl");
1344
+ __publicField(this, "layers");
1345
+ __publicField(this, "version");
1346
+ __publicField(this, "crs");
1347
+ __publicField(this, "format");
1348
+ __publicField(this, "styles");
1349
+ __publicField(this, "transparent");
1350
+ __publicField(this, "attribution");
1351
+ __publicField(this, "tileSize");
1352
+ __publicField(this, "headers");
1353
+ __publicField(this, "extraParams");
1354
+ this.baseUrl = config.baseUrl;
1355
+ this.layers = config.layers;
1356
+ this.version = config.version ?? "1.1.1";
1357
+ this.crs = config.crs ?? "EPSG:3857";
1358
+ this.format = config.format ?? "image/png";
1359
+ this.styles = config.styles ?? "";
1360
+ this.transparent = config.transparent ?? false;
1361
+ this.attribution = config.attribution ?? "WMS Provider";
1362
+ this.tileSize = config.tileSize ?? 256;
1363
+ this.headers = config.headers;
1364
+ this.extraParams = config.extraParams;
1365
+ }
1366
+ getTileUrlFromTileCoords(tileCoords, instance) {
1367
+ return buildWmsGetMapUrl(
1368
+ {
1369
+ baseUrl: instance.baseUrl,
1370
+ layers: instance.layers,
1371
+ version: instance.version,
1372
+ crs: instance.crs,
1373
+ format: instance.format,
1374
+ styles: instance.styles,
1375
+ transparent: instance.transparent,
1376
+ tileSize: instance.tileSize,
1377
+ extraParams: instance.extraParams
1378
+ },
1379
+ tileCoords
1380
+ );
1381
+ }
1382
+ }
1286
1383
  class BaseModel {
1287
1384
  constructor(model_id, providerParams, modelParams) {
1288
1385
  __publicField(this, "providerParams");
@@ -1337,6 +1434,21 @@ class BaseModel {
1337
1434
  scheme: this.providerParams.scheme
1338
1435
  });
1339
1436
  break;
1437
+ case "wms":
1438
+ this.dataProvider = new Wms({
1439
+ baseUrl: this.providerParams.baseUrl,
1440
+ layers: this.providerParams.layers,
1441
+ version: this.providerParams.version,
1442
+ crs: this.providerParams.crs,
1443
+ format: this.providerParams.format,
1444
+ styles: this.providerParams.styles,
1445
+ transparent: this.providerParams.transparent,
1446
+ attribution: this.providerParams.attribution,
1447
+ tileSize: this.providerParams.tileSize,
1448
+ headers: this.providerParams.headers,
1449
+ extraParams: this.providerParams.extraParams
1450
+ });
1451
+ break;
1340
1452
  case "sentinel":
1341
1453
  throw new Error("Sentinel provider not implemented yet");
1342
1454
  default:
package/index.d.ts CHANGED
@@ -162,10 +162,46 @@ declare class Tms extends MapSource {
162
162
  number
163
163
  ], instance: Tms): string;
164
164
  }
165
+ export type WmsVersion = "1.1.1" | "1.3.0";
166
+ export type WmsCrs = "EPSG:3857" | "EPSG:4326";
167
+ export interface WmsGetMapConfig {
168
+ baseUrl: string;
169
+ layers: string;
170
+ version?: WmsVersion;
171
+ crs?: WmsCrs;
172
+ format?: string;
173
+ styles?: string;
174
+ transparent?: boolean;
175
+ tileSize?: number;
176
+ attribution?: string;
177
+ headers?: Record<string, string>;
178
+ extraParams?: Record<string, string>;
179
+ }
180
+ export interface WmsConfig extends WmsGetMapConfig {
181
+ }
182
+ declare class Wms extends MapSource {
183
+ baseUrl: string;
184
+ layers: string;
185
+ version: WmsVersion;
186
+ crs: WmsCrs;
187
+ format: string;
188
+ styles: string;
189
+ transparent: boolean;
190
+ attribution: string;
191
+ tileSize: number;
192
+ headers?: Record<string, string>;
193
+ extraParams?: Record<string, string>;
194
+ constructor(config: WmsConfig);
195
+ protected getTileUrlFromTileCoords(tileCoords: [
196
+ number,
197
+ number,
198
+ number
199
+ ], instance: Wms): string;
200
+ }
165
201
  declare abstract class BaseModel {
166
202
  protected static instance: BaseModel | null;
167
203
  protected providerParams: ProviderParams;
168
- protected dataProvider: Mapbox | Geobase | Esri | Tms | undefined;
204
+ protected dataProvider: Mapbox | Geobase | Esri | Tms | Wms | undefined;
169
205
  protected model_id: string;
170
206
  protected initialized: boolean;
171
207
  protected modelParams?: PretrainedModelOptions;
@@ -470,6 +506,20 @@ export type TmsParams = {
470
506
  headers?: Record<string, string>;
471
507
  scheme?: "WebMercator" | "TMS";
472
508
  };
509
+ export type WmsParams = {
510
+ provider: "wms";
511
+ baseUrl: string;
512
+ layers: string;
513
+ version?: "1.1.1" | "1.3.0";
514
+ crs?: "EPSG:3857" | "EPSG:4326";
515
+ format?: string;
516
+ styles?: string;
517
+ transparent?: boolean;
518
+ attribution?: string;
519
+ tileSize?: number;
520
+ headers?: Record<string, string>;
521
+ extraParams?: Record<string, string>;
522
+ };
473
523
  export interface InferenceInputs {
474
524
  polygon: GeoJSON.Feature;
475
525
  classLabel?: string;
@@ -488,7 +538,7 @@ export interface InferenceParams {
488
538
  postProcessingParams?: PostProcessingParams;
489
539
  mapSourceParams?: MapSourceParams;
490
540
  }
491
- export type ProviderParams = MapboxParams | SentinelParams | GeobaseParams | EsriParams | TmsParams;
541
+ export type ProviderParams = MapboxParams | SentinelParams | GeobaseParams | EsriParams | TmsParams | WmsParams;
492
542
  export type HuggingFaceModelTask = "mask-generation" | "zero-shot-object-detection" | "zero-shot-image-classification" | "object-detection" | "oriented-object-detection" | "image-feature-extraction";
493
543
  export type GeobaseAiModelTask = "damage-assessment" | "vegetation-classification" | "land-cover-classification" | "land-use-classification" | "land-cover-change-detection" | "land-use-change-detection" | "solar-panel-detection" | "ship-detection" | "car-detection" | "wetland-segmentation" | "building-detection" | "oil-storage-tank-detection" | "building-footprint-segmentation";
494
544
  export type ModelInstance = MaskGeneration | ZeroShotObjectDetection | ObjectDetection | OrientedObjectDetection | LandCoverClassification | SolarPanelDetection | ShipDetection | CarDetection | WetLandSegmentation | BuildingDetection | OilStorageTankDetection | BuildingFootPrintSegmentation | ImageFeatureExtraction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geoai",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "A JavaScript library for running Geo AI models in frontend applications",
5
5
  "keywords": [
6
6
  "geoai",