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

Show vector tiles attributes on hover #1296

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions geowebcache/core/src/main/java/org/geowebcache/demo/Demo.java
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ private static String generateHTML(TileLayer layer, String gridSetStr, String fo
+ "#info iframe { width: 100%; height: 250px; border: none; }\n"
+ ".ol-scale-value {top: 24px; right: 8px; position: absolute; }\n"
+ ".ol-zoom-value {top: 40px; right: 8px; position: absolute; }\n"
+ ".tooltip {position: absolute; background-color: white; border: 1px solid black; padding: 5px; border-radius: 3px; white-space: nowrap; max-height: 200px; overflow-y: auto; display: none;}\n"
+ ".tooltip-header {display: flex; justify-content: space-between; align-items: center; padding: 5px; border-bottom: 1pxsolidblack; }\n"
+ ".tooltip-content {padding: 5px; max-height: 150px; overflow-y: auto;}\n"
+ ".close-button {cursor: pointer; background: none; border: none; font-size: 16px; font-weight: bold; }\n"
+ "</style>\n");

buf.append("<script src=\"").append(openLayersPath).append("ol.js\"></script>\n");
Expand All @@ -320,6 +324,14 @@ private static String generateHTML(TileLayer layer, String gridSetStr, String fo
.append("</div>\n");

buf.append("<div id=\"map\"></div>\n" + "<div id=\"info\"></div>\n");
buf.append(
"<div id=\"tooltip\" class=\"tooltip\">\n"
+ " <div class=\"tooltip-header\">\n"
+ " <span>Attributes</span>\n"
+ " <button id=\"close-button\" class=\"close-button\">&times;</button>\n"
+ " </div>\n"
+ " <div id=\"tooltip-content\" class=\"tooltip-content\"></div>\n"
+ " </div>");

// add parameters in hidden inputs
makeHiddenInput(buf, "dpi", Double.toString(gridSubset.getDotsPerInch()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,58 +208,132 @@ window.onload = function() {
map.updateSize();
}

map.on('singleclick', function(evt) {
document.getElementById('info').innerHTML = '';
var tooltip = document.getElementById('tooltip');
var tooltipContent = document.getElementById('tooltip-content');
var closeButton = document.getElementById('close-button');

var source = layer.getSource();
var resolution = view.getResolution();
var tilegrid = source.getTileGrid();
var tileResolutions = tilegrid.getResolutions();
var zoomIdx, diff = Infinity;

for (var i = 0; i < tileResolutions.length; i++) {
var tileResolution = tileResolutions[i];
var diffP = Math.abs(resolution-tileResolution);
if (diffP < diff) {
diff = diffP;
zoomIdx = i;
if (getValue('isVector') != 'true') {
map.on('singleclick', function(evt) {
document.getElementById('info').innerHTML = '';

var source = layer.getSource();
var resolution = view.getResolution();
var tilegrid = source.getTileGrid();
var tileResolutions = tilegrid.getResolutions();
var zoomIdx, diff = Infinity;

for (var i = 0; i < tileResolutions.length; i++) {
var tileResolution = tileResolutions[i];
var diffP = Math.abs(resolution-tileResolution);
if (diffP < diff) {
diff = diffP;
zoomIdx = i;
}
if (tileResolution < resolution) {
break;
}
}
if (tileResolution < resolution) {
break;
var tileSize = tilegrid.getTileSize(zoomIdx);
var tileOrigin = tilegrid.getOrigin(zoomIdx);

var fx = (evt.coordinate[0] - tileOrigin[0]) / (resolution * tileSize[0]);
var fy = (tileOrigin[1] - evt.coordinate[1]) / (resolution * tileSize[1]);
var tileCol = Math.floor(fx);
var tileRow = Math.floor(fy);
var tileI = Math.floor((fx - tileCol) * tileSize[0]);
var tileJ = Math.floor((fy - tileRow) * tileSize[1]);
var matrixIds = tilegrid.getMatrixIds()[zoomIdx];
var matrixSet = source.getMatrixSet();

var url = baseUrl+'?'
for (var param in params) {
if (param.toUpperCase() == 'TILEMATRIX') {
url = url + 'TILEMATRIX='+matrixIds+'&';
} else {
url = url + param + '=' + params[param] + '&';
}
}

url = url
+ 'SERVICE=WMTS&REQUEST=GetFeatureInfo'
+ '&INFOFORMAT=' + infoFormat
+ '&TileCol=' + tileCol
+ '&TileRow=' + tileRow
+ '&I=' + tileI
+ '&J=' + tileJ;
document.getElementById('info').innerHTML =
'<iframe seamless src="' + url.replace(/"/g, "&quot;") + '"></iframe>';
});
} else {
var isPinned = false;

function updateTooltipContent(properties) {
tooltipContent.innerHTML = Object.keys(properties).map(function(key) {
return key + ': ' + properties[key];
}).join('<br>');
}
var tileSize = tilegrid.getTileSize(zoomIdx);
var tileOrigin = tilegrid.getOrigin(zoomIdx);

map.on('pointermove', function(evt) {
if (isPinned) {
return; // Do nothing if the tooltip is pinned
}

var fx = (evt.coordinate[0] - tileOrigin[0]) / (resolution * tileSize[0]);
var fy = (tileOrigin[1] - evt.coordinate[1]) / (resolution * tileSize[1]);
var tileCol = Math.floor(fx);
var tileRow = Math.floor(fy);
var tileI = Math.floor((fx - tileCol) * tileSize[0]);
var tileJ = Math.floor((fy - tileRow) * tileSize[1]);
var matrixIds = tilegrid.getMatrixIds()[zoomIdx];
var matrixSet = source.getMatrixSet();
var pixel = evt.pixel;
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});

var url = baseUrl+'?'
for (var param in params) {
if (param.toUpperCase() == 'TILEMATRIX') {
url = url + 'TILEMATRIX='+matrixIds+'&';
} else {
url = url + param + '=' + params[param] + '&';
}
}
if (feature) {
var coordinates = evt.coordinate;
var properties = feature.getProperties();

url = url
+ 'SERVICE=WMTS&REQUEST=GetFeatureInfo'
+ '&INFOFORMAT=' + infoFormat
+ '&TileCol=' + tileCol
+ '&TileRow=' + tileRow
+ '&I=' + tileI
+ '&J=' + tileJ;
document.getElementById('info').innerHTML =
'<iframe seamless src="' + url.replace(/"/g, "&quot;") + '"></iframe>';
});
// Display the feature properties in the tooltip
updateTooltipContent(properties);

tooltip.style.left = (evt.originalEvent.clientX + 10) + 'px';
tooltip.style.top = (evt.originalEvent.clientY + 10) + 'px';
tooltip.style.display = 'block';
} else {
tooltip.style.display = 'none';
}
});

map.on('singleclick', function(evt) {
if (isPinned) {
// Unpin the tooltip if it's already pinned
isPinned = false;
tooltip.style.display = 'none';
tooltipContent.scrollTop = 0; // Reset scroll position to top
} else {
// Pin the tooltip
var pixel = evt.pixel;
var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});

if (feature) {
var coordinates = evt.coordinate;
var properties = feature.getProperties();

// Display the feature properties in the tooltip
updateTooltipContent(properties);

tooltip.style.left = (evt.originalEvent.clientX + 10) + 'px';
tooltip.style.top = (evt.originalEvent.clientY + 10) + 'px';
tooltip.style.display = 'block';

isPinned = true;
}
}
});

closeButton.addEventListener('click', function() {
tooltip.style.display = 'none';
isPinned = false;
});
}


// set event handlers
function paramHandler(event) {
setParam(event.target.name, event.target.value);
Expand Down
Loading