Skip to content

Commit 979045e

Browse files
committed
Update copilot-instructions.md to reflect current scope of operations
1 parent d870248 commit 979045e

1 file changed

Lines changed: 81 additions & 12 deletions

File tree

.github/copilot-instructions.md

Lines changed: 81 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,58 @@
11
# MapMLify AI Coding Instructions
22

33
## Project Overview
4-
MapMLify is a client-side web application that converts OGC WMS (Web Map Service) capabilities documents into functional MapML map viewers. It uses the `@maps4html/mapml` web components to create interactive map experiences directly in the browser.
4+
MapMLify is a client-side web application that converts geospatial service capabilities documents into functional MapML map viewers. The objective of creating the map viewers is to copy the code for use in external web pages. It uses the `@maps4html/mapml` web components to create interactive map experiences directly in the browser, suitable for copying.
5+
6+
**Supported Services:**
7+
- **OGC WMS** (Web Map Service) - versions 1.1.1 and 1.3.0
8+
- **OGC WMTS** (Web Map Tile Service) - version 1.0.0
9+
- **ESRI REST API MapServer** - both tiled and dynamic (export) modes
10+
- **ESRI REST API ImageServer** - raster imagery services
11+
12+
**Not Yet Supported:**
13+
- ESRI FeatureServer (vector features)
14+
- OGC WFS (Web Feature Service)
15+
- OGC API (Application Programming Interface) services
516

617
**⚠️ Before coding: Read your available skills/tools to understand what capabilities you have for file editing, searching, running commands, etc.**
718

819
## Architecture & Key Concepts
920

1021
### Core Data Flow
11-
1. **Fetch WMS Capabilities** ([main.js](../src/script/main.js#L83-L106)): Attempts direct fetch first, falls back to CORS proxy (`https://corsproxy.io/?`)
12-
2. **Parse XML Capabilities** ([main.js](../src/script/main.js#L112-L269)): Extracts service info, layers, styles, CRS/SRS, bounding boxes, GetFeatureInfo formats
13-
3. **Generate MapML** ([main.js](../src/script/main.js#L620-L770)): Dynamically creates `<mapml-viewer>`, `<map-layer>`, `<map-extent>`, `<map-input>`, `<map-link>` elements
14-
4. **Render Interactive Maps**: MapML web components handle rendering, interaction, and GetFeatureInfo queries
22+
1. **Fetch Capabilities** ([main.js](../src/script/main.js#L83-L106)): Attempts direct fetch first, then prompts user to save local file if CORS issues arise, presents button to read that file from disk (only if CORS issue detected).
23+
2. **Detect Service Type** ([main.js](../src/script/main.js#L234-L270)): Identifies WMS (XML with WMS namespace), WMTS (XML with WMTS namespace), or ESRI (JSON with MapServer/ImageServer indicators)
24+
3. **Parse Capabilities** ([main.js](../src/script/main.js#L112-L269)): Extracts service info, layers, styles, CRS/SRS, bounding boxes, query formats (GetFeatureInfo for WMS/WMTS, identify for ESRI)
25+
4. **Generate MapML** (service-specific functions): Dynamically creates `<mapml-viewer>`, `<map-layer>`, `<map-extent>`, `<map-input>`, `<map-link>` elements
26+
5. **Render Interactive Maps**: MapML web components handle rendering, interaction, and query operations
27+
28+
### Service Type Detection
29+
Service type is detected by examining the response:
30+
- **WMS**: XML root element `Capabilities` with WMS namespace (`http://www.opengis.net/wms`)
31+
- **WMTS**: XML root element `Capabilities` with WMTS namespace (`http://www.opengis.net/wmts/1.0`)
32+
- **ESRI MapServer**: JSON with `layers` array and `tileInfo` (tiled) or `supportedImageFormatTypes` (export)
33+
- **ESRI ImageServer**: JSON with `pixelType` or `serviceDataType` containing `esriImageService`
1534

1635
### WMS Version Handling
1736
The app supports WMS 1.1.1 and 1.3.0, with critical differences:
1837
- **Parameter names**: 1.3.0 uses `CRS`/`I`/`J`, 1.1.1 uses `SRS`/`X`/`Y`
19-
- **BBOX ordering**: WMS 1.3.0 with EPSG:4326 requires lat,lon order (ymin,xmin,ymax,xmax); all other CRS use standard xmin,ymin,xmax,ymax ([main.js](../src/script/main.js#L540-L548))
38+
- **BBOX ordering**: WMS 1.3.0 with EPSG:4326 requires lat,lon order (ymin,xmin,ymax,ymax); all other CRS use standard xmin,ymin,xmax,ymax ([main.js](../src/script/main.js#L540-L548))
2039
- Check version with `version.startsWith('1.3')` pattern throughout codebase
2140

41+
### WMTS Tile Matrix Sets
42+
WMTS services define TileMatrixSet elements that specify zoom levels, tile sizes, and CRS:
43+
- Extract TileMatrixSet identifier and associated TileMatrix elements ([main.js](../src/script/main.js#L393-L450))
44+
- Map TileMatrixSet CRS to MapML projections using `mapTileMatrixSetToProjection()` ([main.js](../src/script/main.js#L376-L392))
45+
- EPSG:4326 requires validation: must have 2×1 tiles at zoom 0 to qualify as WGS84 projection
46+
- ResourceURL templates provide tile and FeatureInfo URL patterns with `{TileMatrix}`, `{TileRow}`, `{TileCol}` variables ([main.js](../src/script/main.js#L564-L574))
47+
48+
### ESRI Service Modes
49+
ESRI MapServer can operate in two modes:
50+
- **Tiled Mode** (`ESRI-MapServer-Tile`): Pre-generated tiles, indicated by presence of `tileInfo` in JSON
51+
- **Export Mode** (`ESRI-MapServer`): Dynamic map generation, uses `export` endpoint with bbox parameters
52+
- **ImageServer**: Always dynamic, uses `exportImage` endpoint
53+
54+
Detection logic in `detectESRIServiceType()` ([main.js](../src/script/main.js#L256-L270))
55+
2256
### Projection System
2357
Four projections are supported, mapped from WMS CRS to MapML units:
2458
- `EPSG:3857``OSMTILE` (Web Mercator) - default
@@ -60,10 +94,13 @@ npm run format # Format all JS files
6094
npm run format:check # Check formatting without changes
6195
```
6296

63-
### Testing WMS Services
97+
### Testing Services
6498
- Preset URLs are loaded from [capabilities.txt](../src/capabilities.txt) with format: `Label,URL` or just `URL`
6599
- Test both direct fetch and CORS proxy scenarios
66-
- Verify behavior across WMS versions (1.1.1 vs 1.3.0)
100+
- **WMS**: Verify behavior across versions (1.1.1 vs 1.3.0)
101+
- **WMTS**: Test services with multiple TileMatrixSets and dimensions
102+
- **ESRI**: Test both tiled and export modes for MapServer; verify ImageServer rendering
103+
- Sample files: `nasa-imagery-wmts.xml` (WMTS), `ducks-MapServer.json` (ESRI MapServer)
67104

68105
## Project-Specific Conventions
69106

@@ -91,27 +128,59 @@ Never attempt partial DOM updates to existing viewers - always rebuild.
91128
## Critical Implementation Details
92129

93130
### Template URL Construction
94-
Build WMS URLs manually as strings to preserve MapML template variables like `{xmin}`, `{w}`, etc.:
131+
132+
**WMS URLs** - Build manually as strings to preserve MapML template variables:
95133
```javascript
96134
let tref = `${currentWmsBaseUrl}?SERVICE=WMS&VERSION=${version}&REQUEST=GetMap&LAYERS=${encodeURIComponent(layer.name)}&WIDTH={w}&HEIGHT={h}...`;
97135
// DON'T use URLSearchParams - it will encode the curly braces
98136
```
99137

138+
**WMTS URLs** - Use ResourceURL templates from capabilities, replace template variables:
139+
```javascript
140+
function buildWMTSTileUrl(template, layer, tileMatrixSet, style, format, zoom, row, col) {
141+
let url = template;
142+
url = url.replace(/{TileMatrixSet}/g, tileMatrixSet);
143+
url = url.replace(/{TileMatrix}/g, zoom);
144+
url = url.replace(/{TileRow}/g, row);
145+
url = url.replace(/{TileCol}/g, col);
146+
// ... replace {Style}, {Layer}, dimension parameters
147+
}
148+
```
149+
150+
**ESRI URLs** - Construct based on service type and mode:
151+
- **MapServer Tile**: `${baseUrl}/tile/{z}/{y}/{x}`
152+
- **MapServer Export**: `${baseUrl}/export?bbox={xmin},{ymin},{xmax},{ymax}&size={w},{h}&format=...`
153+
- **ImageServer**: `${baseUrl}/exportImage?bbox={xmin},{ymin},{xmax},{ymax}&size={w},{h}&format=...`
154+
100155
### Basemap Layer Configuration
101156
Each projection has specific basemap configuration with zoom inputs, tile matrix inputs, and tile URLs ([main.js](../src/script/main.js#L640-L764)). OSMTILE uses dual tile links for geometry and labels. WGS84 has no basemap currently.
102157

103-
### GetFeatureInfo Coordinate Parameters
104-
Map click coordinates use different parameter names:
158+
### Query/Feature Info Handling
159+
160+
**WMS GetFeatureInfo** - Click coordinates use version-specific parameters:
105161
- WMS 1.3.0: `&I={i}&J={j}`
106162
- WMS 1.1.1: `&X={i}&Y={j}`
107163

164+
**WMTS GetFeatureInfo** - Uses ResourceURL templates with `{TileRow}`, `{TileCol}`, `{I}`, `{J}` parameters
165+
- Extract from `<ResourceURL resourceType="FeatureInfo">` elements
166+
- Info formats specified in capabilities as MIME types
167+
168+
**ESRI Identify** - Uses `identify` endpoint:
169+
- **MapServer**: `${baseUrl}/identify?geometry={i},{j}&geometryType=esriGeometryPoint&...`
170+
- **ImageServer**: `${baseUrl}/identify?geometry={i},{j}&geometryType=esriGeometryPoint&...`
171+
- Returns results in JSON format, supports various `returnGeometry` options
172+
108173
## Common Pitfalls
109174

110175
1. **Don't modify existing viewer DOM**: Always remove and recreate viewers when changing configuration
111176
2. **BBOX ordering matters**: WMS 1.3.0 + EPSG:4326 is the ONLY case requiring lat,lon order
112177
3. **Encode layer names**: Use `encodeURIComponent(layer.name)` in URL construction
113-
4. **Root CRS inheritance**: Layers inherit CRS from root `<Capability><Layer>` ([main.js](../src/script/main.js#L148-L153))
178+
4. **Root CRS inheritance** (WMS): Layers inherit CRS from root `<Capability><Layer>` ([main.js](../src/script/main.js#L148-L153))
114179
5. **Map-input attributes**: Location inputs should NOT have min/max attributes ([main.js](../src/script/main.js#L863-L870))
180+
6. **WMTS dimension defaults**: When building preview URLs, replace dimension template variables with default values from capabilities
181+
7. **ESRI coordinate systems**: ESRI services use WKID (e.g., 3857) instead of EPSG codes; extract from `spatialReference.wkid` or `latestWkid`
182+
8. **TileMatrixSet validation**: Not all EPSG:4326 TileMatrixSets are WGS84-compatible; verify 2×1 tile structure at zoom 0
183+
9. **Service type before parsing**: Always detect service type before attempting to parse; JSON vs XML parsers are not interchangeable
115184

116185
## File Organization
117186
- [src/index.html](../src/index.html): Entry point with MapML polyfill import

0 commit comments

Comments
 (0)