Skip to content

Commit

Permalink
WIP on map-link
Browse files Browse the repository at this point in the history
- add map-feature._initialZoom, which captures the zoom of the map
when the feature is first connected. Used by getter for zoom instead
of map-meta or projection zoom for static features only.

- refactor rename map-feature.getMaxZoom() to getZoomToZoom()

- change mapFeature test data (expectations) so that the map-feature
default zoom value for no-zoom-attribute static features is that of
the map viewer when the feature is first connected.

- change mapFeature.test expectations around zooming to the bounds of 
a map-feature that has no zoom attribute - now it will zoom to the 
zoom value or pretty close to the zoom value of the map when the 
feature was first connected (the bounds of a point feature is based 
on the size of a tile at the zoom level of its zoom value, so 
depending on the size of the map it might zoom to a lower zoom than 
that of the point when it was connected).

- eliminate "fallbackZoom" method and argument for creating geometry.
FeatureLayer factory method createGeometry uses map-feature.zoom now

- FeatureLayer._validateRendering checks to see if the layer is on
the map

- geometry _checkRender() now uses map-feature.zoom instead of 
attribute
  • Loading branch information
prushfor authored and prushfor committed Jan 18, 2024
1 parent a0db660 commit 01499c5
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 275 deletions.
48 changes: 10 additions & 38 deletions src/map-feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ export class MapFeature extends HTMLElement {
: this._parentEl.getZoomBounds().maxNativeZoom);
} else {
// for "static" features
// nativeZoom zoom attribute || map-meta zoom || projection maxZoom
// nativeZoom zoom attribute || this._initialZoom
return +(this.hasAttribute('zoom')
? this.getAttribute('zoom')
: meta.value
? meta.value
: projectionMaxZoom);
: this._initialZoom);
}
}

Expand Down Expand Up @@ -187,6 +185,9 @@ export class MapFeature extends HTMLElement {
/* jshint ignore:start */
this.#hasConnected = true;
/* jshint ignore:end */
// set the initial zoom of the map when features connected
// used for fallback zoom getter for static features
this._initialZoom = this.getMapEl().zoom;
this._parentEl =
this.parentNode.nodeName.toUpperCase() === 'LAYER-' ||
this.parentNode.nodeName.toUpperCase() === 'MAP-LINK'
Expand Down Expand Up @@ -236,7 +237,6 @@ export class MapFeature extends HTMLElement {
// this is for re-generating the rendering in case of <geometry> changes
// based on mutation observers. Kinda brute force.
if (this._groupEl.isConnected) {
let fallbackZoom = this._getFallbackZoom();
let fallbackCS = this._getFallbackCS();
let placeholder = document.createElement('span');
this._groupEl.insertAdjacentElement('beforebegin', placeholder);
Expand All @@ -246,7 +246,7 @@ export class MapFeature extends HTMLElement {
layerToRenderOn.removeLayer(this._geometry);
// Garbage collection needed
this._geometry = layerToRenderOn
.createGeometry(this, fallbackCS, fallbackZoom) // side effect: this._groupEl set
.createGeometry(this, fallbackCS) // side effect: this._groupEl set
.addTo(layerToRenderOn);
placeholder.replaceWith(this._geometry.options.group);
layerToRenderOn._validateRendering();
Expand Down Expand Up @@ -279,14 +279,9 @@ export class MapFeature extends HTMLElement {
let parentLayer = this.getLayerEl();
// "synchronize" the event handlers between map-feature and <g>
if (!this.querySelector('map-geometry')) return;
let fallbackZoom = this._getFallbackZoom();
let fallbackCS = this._getFallbackCS();
let content = parentLayer.src ? parentLayer.shadowRoot : parentLayer;
this._geometry = layerToAddTo.createGeometry(
this,
fallbackCS,
fallbackZoom
); // side effect: extends `this` with this._groupEl, points to svg g element that renders to map SD
this._geometry = layerToAddTo.createGeometry(this, fallbackCS); // side effect: extends `this` with this._groupEl, points to svg g element that renders to map SD
layerToAddTo.addLayer(this._geometry);
this._setUpEvents();
}
Expand Down Expand Up @@ -315,27 +310,6 @@ export class MapFeature extends HTMLElement {
});
}

// native zoom: used by FeatureLayer.createGeometry(...),
// the fallback zoom for map-feature if its zoom attribute is not specified
// for query and templated features, fallback zoom is the current map zoom level
// for static features, fallback zoom is map-meta[name="zoom"] value in layer- || the current map zoom level
_getFallbackZoom() {
if (this._parentEl.nodeName === 'MAP-LINK') {
// feature attaches to link's shadow
return this.getMapEl().zoom;
} else {
// feature attaches to the layer- / layer-'s shadow
let layerEl = this.getLayerEl();
let zoomMeta = layerEl.src
? layerEl.shadowRoot.querySelector('map-meta[name=zoom]')
: layerEl.querySelector('map-meta[name=zoom]');
return (
M._metaContentToObject(zoomMeta?.getAttribute('content'))?.value ||
this.getMapEl().zoom
);
}
}

// native cs: used by FeatureLayer._geometryToLayer(...),
// the fallback cs for map-geometry if its cs attribute is not specified
_getFallbackCS() {
Expand Down Expand Up @@ -378,9 +352,7 @@ export class MapFeature extends HTMLElement {
geometry = this.querySelector('map-geometry'),
cs = geometry.getAttribute('cs') || this._getFallbackCS(),
// zoom level that the feature rendered at
zoom = +(this.hasAttribute('zoom')
? this.getAttribute('zoom')
: this._getFallbackZoom()),
zoom = this.zoom,
shapes = geometry.querySelectorAll(
'map-point, map-linestring, map-polygon, map-multipoint, map-multilinestring'
),
Expand Down Expand Up @@ -471,7 +443,7 @@ export class MapFeature extends HTMLElement {
maxNativeZoom: this.zoom
};
}
getMaxZoom() {
getZoomToZoom() {
let tL = this.extent.topLeft.pcrs,
bR = this.extent.bottomRight.pcrs,
bound = L.bounds(
Expand Down Expand Up @@ -672,7 +644,7 @@ export class MapFeature extends HTMLElement {
L.point(bR.horizontal, bR.vertical)
),
center = map.options.crs.unproject(bound.getCenter(true));
map.setView(center, this.getMaxZoom(), { animate: false });
map.setView(center, this.getZoomToZoom(), { animate: false });
}
whenReady() {
return new Promise((resolve, reject) => {
Expand Down
8 changes: 3 additions & 5 deletions src/mapml/features/geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,15 @@ export var Geometry = L.FeatureGroup.extend({
* Check whether the feature group should be rendered at current map zoom level
* @param {Number} zoom - current map zoom
* @param {Object} vectorMinZoom - the minimum zoom bound of vector layer
* @param {Object} vectorMinZoom - the maximum zoom bound of vector layer
* @param {Object} vectorMaxZoom - the maximum zoom bound of vector layer
* @returns {Boolean}
* @private
*/
_checkRender: function (zoom, vectorMinZoom, vectorMaxZoom) {
let minZoom = this._featureEl.getAttribute('min'),
maxZoom = this._featureEl.getAttribute('max');
let minZoom = this._featureEl.min,
maxZoom = this._featureEl.max;
// if the current map zoom falls below/above the zoom bounds of the vector layer
if (zoom > vectorMaxZoom || zoom < vectorMinZoom) return false;
// if no min and max attribute present
if (minZoom === null && maxZoom === null) return true;
// if the current map zoom falls below/above the [min, max] range
if (
(minZoom !== null && zoom < +minZoom) ||
Expand Down
11 changes: 6 additions & 5 deletions src/mapml/layers/FeatureLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ export var FeatureLayer = L.FeatureGroup.extend({
delete this.layerBounds;
delete this.zoomBounds;
delete this._layers[featureToRemove._leaflet_id];
_removeFromFeaturesList(featureToRemove);
this._removeFromFeaturesList(featureToRemove);
// iterate through all remaining layers
let layerBounds, zoomBounds;
let layerIds = Object.keys(this._layers);
Expand Down Expand Up @@ -296,6 +296,10 @@ export var FeatureLayer = L.FeatureGroup.extend({
// since features are removed and re-added by zoom level, need to clean the feature index before re-adding
if (this._map) this._map.featureIndex.cleanIndex();
let map = this._map || this.options._leafletLayer._map;
// it's important that we not try to validate rendering if the FeatureLayer
// isn't actually being rendered (i.e. on the map. the _map property can't
// be used because once it's assigned (by onAdd, above) it's never unassigned.
if (!map.hasLayer(this)) return;
if (this._features) {
for (let zoom in this._features) {
for (let k = 0; k < this._features[zoom].length; k++) {
Expand Down Expand Up @@ -358,14 +362,11 @@ export var FeatureLayer = L.FeatureGroup.extend({
*
* @param <map-feature> feature
* @param {String} fallbackCS - "gcrs" | "pcrs"
* TODO: evaluate to delete fallbackZoom parameter
* @param {Integer} fallbackZoom - the zoom level to use for "zoomTo()" if the
* feature geometry doesn't have a zoom attribute
*
* @returns M.Geometry, which is an L.FeatureGroup
* @public
*/
createGeometry: function (feature, fallbackCS, fallbackZoom) {
createGeometry: function (feature, fallbackCS) {
let options = this.options;

if (options.filter && !options.filter(feature)) {
Expand Down
4 changes: 3 additions & 1 deletion src/mapml/layers/MapMLLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,9 @@ export var MapMLLayer = L.LayerGroup.extend({
L.latLng(bR.horizontal, bR.vertical)
).getCenter(true);
let zoomLink = document.createElement('a');
zoomLink.href = `#${featureEl.getMaxZoom()},${center.lng},${center.lat}`;
zoomLink.href = `#${featureEl.getZoomToZoom()},${center.lng},${
center.lat
}`;
zoomLink.innerHTML = `${M.options.locale.popupZoom}`;
zoomLink.className = 'mapml-zoom-link';
zoomLink.onclick = zoomLink.onkeydown = function (e) {
Expand Down
6 changes: 1 addition & 5 deletions src/mapml/layers/TemplatedTileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,7 @@ export var TemplatedTileLayer = L.TileLayer.extend({
let fallback = M.getNativeVariables(markup);
let features = markup.querySelectorAll('map-feature');
for (let i = 0; i < features.length; i++) {
let feature = tileFeatures.createGeometry(
features[i],
fallback.cs,
fallback.zoom
);
let feature = tileFeatures.createGeometry(features[i], fallback.cs);
for (let featureID in feature._layers) {
let layer = feature._layers[featureID];
M.FeatureRenderer.prototype._initPath(layer, false);
Expand Down
Loading

0 comments on commit 01499c5

Please sign in to comment.