Skip to content
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

dynamically update the layer projection based on map-extents and hence update map-projection if neccessary #912

Open
AliyanH opened this issue Nov 15, 2023 · 0 comments

Comments

@AliyanH
Copy link
Member

AliyanH commented Nov 15, 2023

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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant