Skip to content

Add zooming when layer is added using <map-a> #387

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

Merged
merged 12 commits into from
Apr 13, 2021
37 changes: 37 additions & 0 deletions src/layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,4 +302,41 @@ export class MapLayer extends HTMLElement {
{target: this}}));
},this);
}
focus(){
if(!this.extent) return;
let map = this._layer._map,
tL = this.extent.topLeft.pcrs,
bR = this.extent.bottomRight.pcrs,
layerBounds = L.bounds(L.point(tL.horizontal, tL.vertical), L.point(bR.horizontal, bR.vertical)),
center = map.options.crs.unproject(layerBounds.getCenter(true)),
currentZoom = map.getZoom();

map.setView(center, currentZoom, {animate:false});
let mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);

//fits the bounds to the map view
if(mapBounds.contains(layerBounds)){
while(mapBounds.contains(layerBounds) && (currentZoom + 1) <= this.extent.zoom.maxZoom){
currentZoom++;
map.setView(center, currentZoom, {animate:false});
mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);
}
if(currentZoom - 1 >= 0) map.flyTo(center, (currentZoom - 1));
} else {
while(!(mapBounds.contains(layerBounds)) && (currentZoom - 1) >= this.extent.zoom.minZoom){
currentZoom--;
map.setView(center, currentZoom, {animate:false});
mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);
}
}
}
}
4 changes: 2 additions & 2 deletions src/mapml-viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,8 @@ export class MapViewer extends HTMLElement {
}
}
zoomTo(lat, lon, zoom) {
zoom = Number.isInteger(zoom)? zoom:this.zoom;
var location = new L.LatLng(lat,lon);
zoom = Number.isInteger(+zoom) ? +zoom : this.zoom;
let location = new L.LatLng(+lat, +lon);
this._map.setView(location, zoom);
this.zoom = zoom;
this.lat = location.lat;
Expand Down
33 changes: 9 additions & 24 deletions src/mapml/features/feature.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,42 +49,24 @@ export var Feature = L.Path.extend({
this.isClosed = this._isClosed();
},

/**
* Removes the focus handler, and calls the leaflet L.Path.onRemove
*/
onRemove: function () {
if(this.options.link) {
this.off({
click: this._handleLinkClick,
keypress: this._handleLinkKeypress,
});
}

if(this.options.interactive) this.off('keypress', this._handleSpaceDown);

L.Path.prototype.onRemove.call(this);
},

/**
* Attaches link handler to the sub parts' paths
* @param path
* @param link
* @param linkTarget
* @param linkType
* @param leafletLayer
*/
attachLinkHandler: function (path, link, linkTarget, linkType, leafletLayer) {
attachLinkHandler: function (path, link, leafletLayer) {
let drag = false; //prevents click from happening on drags
L.DomEvent.on(path, 'mousedown', () =>{ drag = false;}, this);
L.DomEvent.on(path, 'mousemove', () =>{ drag = true;}, this);
L.DomEvent.on(path, "mouseup", (e) => {
L.DomEvent.stop(e);
if(!drag) M.handleLink(link, linkTarget, linkType, leafletLayer);
if(!drag) M.handleLink(link, leafletLayer);
}, this);
L.DomEvent.on(path, "keypress", (e) => {
L.DomEvent.stop(e);
if(e.keyCode === 13 || e.keyCode === 32)
M.handleLink(link, linkTarget, linkType, leafletLayer);
M.handleLink(link, leafletLayer);
}, this);
},

Expand Down Expand Up @@ -159,9 +141,12 @@ export var Feature = L.Path.extend({
}*/
classList +=`${elem.className} `;
} else if(!output.link && elem.getAttribute("href")) {
output.link = elem.getAttribute("href");
if(elem.hasAttribute("target")) output.linkTarget = elem.getAttribute("target");
if(elem.hasAttribute("type")) output.linkType = elem.getAttribute("type");
let link = {};
link.url = elem.getAttribute("href");
if(elem.hasAttribute("target")) link.target = elem.getAttribute("target");
if(elem.hasAttribute("type")) link.type = elem.getAttribute("type");
if(elem.hasAttribute("inplace")) link.inPlace = true;
output.link = link;
}
}
output.className = `${classList} ${this.options.className}`.trim();
Expand Down
8 changes: 2 additions & 6 deletions src/mapml/features/featureGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@ export var FeatureGroup = L.FeatureGroup.extend({
L.DomUtil.addClass(this.options.group, "leaflet-interactive");
L.DomEvent.on(this.options.group, "keyup keydown mousedown", this._handleFocus, this);
let firstLayer = layers[Object.keys(layers)[0]];
if(layers.length === 1 && firstLayer.options.link){ //if it's the only layer and it has a link, take it's link
this.options.link = firstLayer.options.link;
this.options.linkTarget = firstLayer.options.linkTarget;
this.options.linkType = firstLayer.options.linkType;
}
if(layers.length === 1 && firstLayer.options.link) this.options.link = firstLayer.options.link;
if(this.options.link){
M.Feature.prototype.attachLinkHandler.call(this, this.options.group, this.options.link, this.options.linkTarget, this.options.linkType, this.options._leafletLayer);
M.Feature.prototype.attachLinkHandler.call(this, this.options.group, this.options.link, this.options._leafletLayer);
} else {
this.options.group.setAttribute("aria-expanded", "false");
this.options.onEachFeature(this.options.properties, this);
Expand Down
4 changes: 2 additions & 2 deletions src/mapml/features/featureRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export var FeatureRenderer = L.SVG.extend({
if (p.path)
layer.group.appendChild(p.path);
if (interactive){
if(layer.options.link) layer.attachLinkHandler(p.path, layer.options.link, layer.options.linkTarget, layer.options.linkType, layer.options._leafletLayer);
if(layer.options.link) layer.attachLinkHandler(p.path, layer.options.link, layer.options._leafletLayer);
layer.addInteractiveTarget(p.path);
}

Expand All @@ -100,7 +100,7 @@ export var FeatureRenderer = L.SVG.extend({
for (let subP of p.subrings) {
if (subP.path) {
if (subP.link){
layer.attachLinkHandler(subP.path, subP.link, subP.linkTarget, subP.linkType, layer.options._leafletLayer);
layer.attachLinkHandler(subP.path, subP.link, layer.options._leafletLayer);
layer.addInteractiveTarget(subP.path);
}
layer.group.appendChild(subP.path);
Expand Down
37 changes: 2 additions & 35 deletions src/mapml/handlers/ContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,41 +195,8 @@ export var ContextMenu = L.Handler.extend({
},

_zoomToLayer: function (e) {
let map = e instanceof KeyboardEvent ? this._map : this,
layerElem = map.contextMenu._layerClicked.layer._layerEl,
tL = layerElem.extent.topLeft.pcrs,
bR = layerElem.extent.bottomRight.pcrs,
layerBounds = L.bounds(L.point(tL.horizontal, tL.vertical), L.point(bR.horizontal, bR.vertical)),
center = map.options.crs.unproject(layerBounds.getCenter(true)),
currentZoom = map.getZoom();

map.setView(center, currentZoom, {animate:false});
let mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);

//fits the bounds to the map view
if(mapBounds.contains(layerBounds)){
while(mapBounds.contains(layerBounds) && (currentZoom + 1) <= layerElem.extent.zoom.maxZoom){
currentZoom++;
map.setView(center, currentZoom, {animate:false});
mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);
}
if(currentZoom - 1 >= 0) map.flyTo(center, (currentZoom - 1));
} else {
while(!(mapBounds.contains(layerBounds)) && (currentZoom - 1) >= layerElem.extent.zoom.minZoom){
currentZoom--;
map.setView(center, currentZoom, {animate:false});
mapBounds = M.pixelToPCRSBounds(
map.getPixelBounds(),
map.getZoom(),
map.options.projection);
}
}
let context = e instanceof KeyboardEvent ? this._map.contextMenu : this.contextMenu;
context._layerClicked.layer._layerEl.focus();
},

_goForward: function(e){
Expand Down
1 change: 1 addition & 0 deletions src/mapml/layers/MapLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ export var MapMLLayer = L.Layer.extend({
layer.error = true;
}
layer.fire('extentload', layer, false);
layer._layerEl.dispatchEvent(new CustomEvent('extentload', {detail: layer,}));
}
},
_createExtent: function () {
Expand Down
69 changes: 45 additions & 24 deletions src/mapml/utils/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,31 +322,52 @@ export var Util = {
this.push(parseFloat(element));
},

handleLink: function (link, linkTarget, linkType, leafletLayer) {
let layer = document.createElement('layer-');
if(linkType === "text/html" && linkTarget !== "_blank") linkTarget = "_top";
layer.setAttribute('src', link);
layer.setAttribute('checked', '');
switch (linkTarget) {
case "_blank":
if(linkType === "text/html"){
window.open(link);
} else {
handleLink: function (link, leafletLayer) {
let zoomTo, justPan = false, layer;
if(link.type === "text/html" && link.target !== "_blank"){ // all other target values other than blank behave as _top
link.target = "_top";
} else if (link.type !== "text/html" && link.url.includes("#")){
let hash = link.url.split("#"), loc = hash[1].split(",");
zoomTo = {z: loc[0] || 0, lng: loc[1] || 0, lat: loc[2] || 0};
justPan = !hash[0]; // if the first half of the array is an empty string then the link is just for panning
if(["/", ".","#"].includes(link.url[0])) link.target = "_self";
}
if(!justPan) {
let newLayer = false;
layer = document.createElement('layer-');
layer.setAttribute('src', link.url);
layer.setAttribute('checked', '');
switch (link.target) {
case "_blank":
if (link.type === "text/html") {
window.open(link.url);
} else {
leafletLayer._map.options.mapEl.appendChild(layer);
newLayer = true;
}
break;
case "_parent":
for (let l of leafletLayer._map.options.mapEl.querySelectorAll("layer-"))
if (l._layer !== leafletLayer) leafletLayer._map.options.mapEl.removeChild(l);
leafletLayer._map.options.mapEl.appendChild(layer);
leafletLayer._map.options.mapEl.removeChild(leafletLayer._layerEl);
newLayer = true;
break;
case "_top":
window.location.href = link.url;
break;
default:
leafletLayer._layerEl.insertAdjacentElement('beforebegin', layer);
leafletLayer._map.options.mapEl.removeChild(leafletLayer._layerEl);
newLayer = true;
}
if(!link.inPlace && newLayer) L.DomEvent.on(layer,'extentload', function focusOnLoad(e) {
if(layer.extent){
if(zoomTo) layer.parentElement.zoomTo(+zoomTo.lat, +zoomTo.lng, +zoomTo.z);
else layer.focus();
L.DomEvent.off(layer, 'extentload', focusOnLoad);
}
break;
case "_parent":
for(let l of leafletLayer._map.options.mapEl.querySelectorAll("layer-"))
if(l._layer !== leafletLayer) leafletLayer._map.options.mapEl.removeChild(l);
leafletLayer._map.options.mapEl.appendChild(layer);
leafletLayer._map.options.mapEl.removeChild(leafletLayer._layerEl);
break;
case "_top":
window.location.href = link;
break;
default:
leafletLayer._layerEl.insertAdjacentElement('beforebegin', layer);
leafletLayer._map.options.mapEl.removeChild(leafletLayer._layerEl);
}
});
} else if (zoomTo && !link.inPlace && justPan) leafletLayer._map.options.mapEl.zoomTo(+zoomTo.lat, +zoomTo.lng, +zoomTo.z);
},
};
4 changes: 2 additions & 2 deletions src/web-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,8 @@ export class WebMap extends HTMLMapElement {
}
}
zoomTo(lat, lon, zoom) {
zoom = Number.isInteger(zoom)? zoom:this.zoom;
var location = new L.LatLng(lat,lon);
zoom = Number.isInteger(+zoom) ? +zoom : this.zoom;
let location = new L.LatLng(+lat, +lon);
this._map.setView(location, zoom);
this.zoom = zoom;
this.lat = location.lat;
Expand Down
15 changes: 14 additions & 1 deletion test/e2e/core/featureLinks.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ <h1>Test</h1>
</feature>

<feature zoom="2" class="refDiff">
<featurecaption>Inplace</featurecaption>
<properties>
<h1>Test</h1>
</properties>
Expand All @@ -77,7 +78,7 @@ <h1>Test</h1>
<polygon>
<coordinates>2771 3106 2946 3113 2954 3210 2815 3192</coordinates>
</polygon>
<map-a href="http://geogratis.gc.ca/mapml/en/cbmtile/fdi/" target="_blank">
<map-a href="http://geogratis.gc.ca/mapml/en/cbmtile/fdi/" target="_blank" inplace>
<point>
<coordinates>2745 3218</coordinates>
</point>
Expand Down Expand Up @@ -124,6 +125,18 @@ <h1>Test</h1>
</map-a>
</geometry>
</feature>
<feature zoom="2" class="refDiff">
<properties>
<h1>Test</h1>
</properties>
<geometry cs="tilematrix">
<map-a href="data/vector-tile-test.mapml#2,-98,37" target="_blank">
<polygon>
<coordinates>10.5 11 10.75 11 10.75 11.25 10.5 11.25 10.5 11</coordinates>
</polygon>
</map-a>
</geometry>
</feature>
</layer->
</map>

Expand Down
Loading