Skip to content

Add <map-tile> to support principally GeoServer layer group processing #1033

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c445dea
Add map-tile element
May 2, 2025
e69f9f5
Unbreak a few tests, more to do.
May 9, 2025
15bf2ed
Unbreak a few more tests, more to do.
May 14, 2025
478455b
Unbreak multipleExtents.test.js. Keep this commit separate perhaps, as
May 14, 2025
592fda4
Add temporary debug logging to TemplatedTileLayer.js
prushforth May 14, 2025
8c04446
Restore / add redraw method to TemplatedFeaturesOrTilesLayerGroup
prushforth May 14, 2025
bee4b65
Tentative stab at <map-tile> rendering in TemplatedTileLayer.js
May 14, 2025
f659f50
Tweak TemplatedTileLayer._createFeatures method to render tiles
prushforth May 14, 2025
8f1f829
Optimize tile image loading for <map-tile>
prushforth May 14, 2025
39430f6
Optimize tile image loading for <map-tile>s that connect to DOM.
prushforth May 14, 2025
53453f8
Rename MapFeatureLayerGroup -> MapFeatureLayer
Jul 6, 2025
df4c1ad
Rename TemplatedFeaturesOrTilesLayerGroup to TemplatedFeaturesOrTiles…
prushforth Jul 6, 2025
0f1dc1d
Rename MapMLLayer.js -> MapLayer.js
prushforth Jul 7, 2025
f726e63
Update To Do list
prushforth Jul 7, 2025
ecf9a27
Rename ExtentLayer.js to MapExtentLayer.js
Jul 8, 2025
2f1d76e
Remove link to StaticTileLayer.js prior to deleting it. A few tests
Jul 8, 2025
d885084
Fixing a few more tests. Main one to fix now is customTCRS.test.js,
Jul 9, 2025
e1c4db5
Update map-layer._validateDissabled() to take into account removal of
prushforth Jul 10, 2025
5a8bb89
Update To Do
prushforth Jul 10, 2025
15b8966
Update <map-layer>._validateDisabled to eliminate compile error due
Jul 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions .github/workflows/ci-testing.yml

This file was deleted.

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
/test-results/
.idea/
*.iml
test.html
test.html
**/.claude/settings.local.json
24 changes: 24 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build and Test Commands
- Build project: `grunt default`
- Format and lint: `grunt format`
- Run tests: `npx playwright test`
- Run single test: `npx playwright test test/e2e/path/to/test.test.js`
- Start test server: `node test/server.js`
- Test with specific browser: `npx playwright test --project=chromium`

## Code Style Guidelines
- JavaScript: ES6+, esversion 11
- Formatting: Prettier with singleQuote: true, trailingComma: "none"
- Testing: Playwright for E2E tests, Jest for unit tests
- Style the code like existing files, following established patterns
- Use jshint for linting
- Components use custom HTML elements pattern
- Prefer absolute paths over relative paths
- MapML is a custom extension of HTML for maps
- Prefer async/await in test files
- Error handling should follow existing patterns in similar code
- Include meaningful test descriptions
133 changes: 133 additions & 0 deletions ToDo
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
map-tile.js has a function _createOrGetTileLayer which either constructs a new
MapTileLayer or obtains a reference to it from a previous <map-tile>.

- The map-tile.js has a property called _parentElement which refers to either
the map-link that is responsible for loading the tile, or the map-layer, taking
into account that the tile may be connected in a shadow root. That code is probably
duplicative of similar code in <map-feature> and should be de-duped if possible.

Could a src/mapml/elementSupport/file.js be used to import common functions to
map-tile, map-feature etc i.e. getMapEl etc.?

ANYWAY, if map-tile invokes the constructor of MapTileLayer during _createOrGetTileLayer,
it sets the options.pane to parentElement._templatedLayer.getContainer(). If we
want that to work for MapLayer equally, we would want to use MapLayer.getContainer(),
I think (DONE which needs to be implemented). THEN it invokes the (LayerGroup) addLayer(layer)
where layer is set to the constructed MapTileLayer. If the constructor is not
invoked (i.e. the map-tile is not the 1st in a sequence of map-tiles), the code
obtains the reference to the MapTileLayer and invokes addMapTile(this).

map-feature.js has a similar method called _createOrGetFeatureLayer that seems to be
a new feature of map-feature probably introduced when TemplatedFeaturesOrTilesLayer
was introduced, because again it depends on the templated layer and needs to be
generalized to the other use cases, specifically for use with MapLayer.

DONE Could "TemplatedFeaturesOrTilesLayerGroup" be renamed to reduce cognitive burden?
- to consider: semantic overlap with TemplatedTileLayer

MapFeatureLayer and MapTileLayer are intended to work (together) as individual layers
in a LayerGroup. On the one hand, we have TemplatedFeaturesOrTilesLayerGroup as
a parent layer, and on the other we have MapLayer which acts as a parent container
but in an odd way - see StaticTileLayer and how the FeatureLayer is constructed and
used.

There is a privileged relation between <map-feature> and (Map)FeatureLayer, as well,
which is determined by how the (Map)FeatureLayer is constructed, in contrast to how it
is constructed by MapLayer, as well as how it's constructed during a query.

An additional complication is that (Map)FeatureLayer uses a custom renderer, and the custom
renderer has some behaviour that is a bit odd for a renderer, at least from an
outside perspective.

IN PROGRESS task -use MapLayer (a LayerGroup) in the same role as
TemplatedFeaturesOrTilesLayerGroup, EXCEPT that a MapLayer can have
<map-extent>, <map-feature> and/or <map-tile> in any order, whereas a
TemplatedFeaturesOrTilesLayerGroup can ONLY have <map-feature> and/or <map-tile>

- to accomplish above, <map-extent> would have to behave like <map-tile>, in that
it would have to add its own LayerGroup to the parent MapLayer's LayerGroup
(I think it must do this already - CHECK IT).

Idea: should/could we rename Templated* layers to MapLink* so that they are visually
associated to the <map-link> element? Currently, there's no "MapLinkLayer", but
these could all potentially be subclasses of MapLinkLayer, tbd, sharing some
common code, perhaps?? map-link.js itself might be that common code, but we should
investigate if there's any behaviour implemented across those layers that could
be consolidated.

DONE rename MapMLLayer to MapLayer for consistency with the custom element name?

Could we rename mapml- to map-document, and provide backwards-compatibility to the
old name?

DONE Rename ExtentLayer to MapExtentLayer

FeatureLayer is fundamental currently. How to get rid of? We don't: we replace
it with MapFeatureLayer. MapFeatureLayer gets inserted into the MapLayer.layers
(LayerGroup) array (via LayerGroup.addLayer(l)) when the <map-feature> attaches
to the DOM.
- the MapLayer currently has a ._mapmlvectors property, that should be removed,
managed by the inherent LayerGroup-ness of MapLayer.
- also, the MapLayer currently has ._mapmlTileContainer and ._staticTileLayer which
should be removed and managed via the LayerGroup per features

There is ImageLayer, but no MapImage element. Is this a shortcoming? TBD


NOTE: In order to get the staticTileLayer test working specifically the extent test
within that, I changed the <map-layer>.extent getter so that it always runs the
bounds calculation, not relying on pre-existing value of _layer.bounds, which was
turning out incorrect, not sure why. That was an optimization that was perhaps
premature??

Layer with only inline tiles never seems to be not disabled/enabled. what gives,
add a test for that.


Take a look at the introductory comment in MapExtentLayer.js, MapTileLayer.js and
MapFeatureLayer.js which illustrates the custom elements model that will be implemented by the
target code state.

MapExtentLayer and MapTileLayer have been refactored to become member layers
in the MapLayer LayerGroup, although MapExtentLayer has some differences because it
implements the <map-extent> element which has the checked attribute controlling
how it is added or removed from the map, hence the map-extent._handleChange event handling
method which is tied to the checked attribute, and associated to the <input type="checkbox">
representation of the <map-extent> in the layer control (as a "sub-layer").
The MapExtentLayer is added/removed to/from the map-layer._layer (instance of
MapLayer) LayerGroup by the map-extent._handleChange method. This makes sense
because while the map-layer._layer may be on the map (added to the Leaflet map),
the map-extent._extentLayer may not be, due to the map-extent.checked (absent/false value)
attribute. In other words, the _extentLayer itself will or will not be a member of
the map-layer._layer._layers (LayerGroup) collection, according to the associated
<map-layer>.checked value.

The MapTileLayer instance(s) associated to sequences of <map-tile> elements in the
content of the MapLayer is / are always members of the <map-layer>._layer._layers
(LayerGroup instance), because the <map-tile> element isn't controlled by a checked
attribute, and individual <map-tile>s are rendered on demand according to their
row,col,zoom due to being rendered by the MapTileLayer (GridLayer) internal tile
management. The MapTileLayer in which a <map-tile> is a member is always included
in the <map-layer>._layer._layers (MapLayer LayerGroup instance), and therefore is
on the map or not on the map according to the <map-layer>.checked value.

Now I need to refactor FeatureLayer (now copied to
MapFeatureLayer.js with the new header comment), map-feature.js and MapFeature.js to
work in all the contexts that FeatureLayer currently works. I want to apply a similar architecture to
<map-feature> / MapFeatureLayer.js as I have done to <map-tile> / MapTileLayer. and
<map-extent> / MapExtentLayer.js, but this step is more complex and has greater
ramifications on testing especially. The code in the _initialize processFeatures function will be the first
code to be deleted. That code creates a single MapLayer._mapmlvectors member variable
but that is simplistic: each *set* of adjacent <map-feature> elements in the
inline or remote content should create a single MapFeatureLayer wherein the first
such <map-feature> creates the MapFeatureLayer (a Leaflet FeatureGroup), and
subsequent *adjacent* <map-feature> elements are added to that MapFeatureLayer
FeatureGroup by the <map-feature> connectedCallback chain, much as is already done
by the <map-tile> connectedCallback (in which case, the collection layer is a
MapTileLayer GridLayer). On the other hand, <map-feature> elements which add themselves
to the map-layer._layer LayerGroup aren't removed unless and until the <map-feature>
element itself is removed - these <map-feature> elements are what is currently
handled by MapLayer._initialize.processFeatures, so this is the first bit related
to MapFeatureLayer to get refactored.

The next use of MapFeatureLayer is
Loading