Open
Description
As pointed by @yhy0217 When removing a map-extent from a single layer in a map, the other map-extents should be used to calculate the projection of the layer.
Relevant to #911
We devised an early method (similar to determineLayerProjection, which should be merged to this method) for layer.js to help with this, which is called from map-extent disconnected Callback and can also be called from the layer disconnectedcallback:
// update the layer projection based on it's children, used if map-meta is appended or map-extents are removed
validateLayerProjection() {
let meta = this.shadowRoot
? this.shadowRoot.querySelector('map-meta[name=projection][content]')
: this.querySelector('map-meta[name=projection][content]');
// if map-meta for project exists use it primarily
if (meta) {
let metaProjection = M._metaContentToObject(
meta.getAttribute('content')
).content;
if (
metaProjection.toUpperCase() !==
this._layer._properties.projection.toUpperCase()
) {
this._layer._properties.projection = metaProjection.toUpperCase();
}
} else {
// otherwise use map-extents to check if projection can be updated
let extents = this.shadowRoot
? this.shadowRoot.querySelectorAll('map-extent')
: this.querySelectorAll('map-extent');
let match = true;
for (let i = 0; i < extents.length; i++) {
if (extents[i].units.toUpperCase() !== extents[0].units.toUpperCase()) {
match = false;
break;
}
}
// if all map-extents have same projection, update layer projection
if (match) {
this._layer._properties.projection = extents[0].units;
} else {
// change projection to map-projection, similar to what is done in initialization
// in determineLayerProjection
this._layer._properties.projection = this._layer.options.mapprojection;
}
}
// check if only layer for mapml-viewer and to update the map projection if needed
if (
this._layer._properties.projection !==
this._layer.options.mapprojection &&
this.parentElement.layers.length === 1
) {
this.parentElement.projection = this._layer._properties.projection;
}
}
Steps to reproduce, paste the following to https://maps4html.org/web-map-doc/demo/sandbox/ and remove the OSMTILE map-extent
, expected outcome should be that the map changes projection to CBMTILE to display the CBMTILE map-extent as it is the only layer in the map:
<mapml-viewer height="700" zoom="15" lon="-75.703611" lat="45.411105" controls projection="OSMTILE">
<layer- label="Projection changer" checked>
<map-extent label="National Geographic" units="OSMTILE" checked >
<map-input name="TileMatrix" type="zoom" value="18" min="0" max="18"></map-input>
<map-input name="TileCol" type="location" units="tilematrix" axis="column" min="0" max="262144"></map-input>
<map-input name="TileRow" type="location" units="tilematrix" axis="row" min="0" max="262144"></map-input>
<map-link rel="tile" tref="https://server.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer/WMTS/tile/1.0.0/NatGeo_World_Map/default/default028mm/{TileMatrix}/{TileRow}/{TileCol}.jpg"></map-link>
</map-extent>
<map-extent label="Canada Base Map - Transportation" units="CBMTILE" checked >
<map-input name="z" type="zoom" min="0" max="18"></map-input>
<map-input name="y" type="location" units="tilematrix" axis="row"></map-input>
<map-input name="x" type="location" units="tilematrix" axis="column"></map-input>
<map-link rel="tile" tref="https://geoappext.nrcan.gc.ca/arcgis/rest/services/BaseMaps/CBMT3978/MapServer/tile/{z}/{y}/{x}?m4h=t" ></map-link>
</map-extent>
</layer->
</mapml-viewer>