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

fix: sharemap popup not displayed #1904

Merged
merged 2 commits into from
Nov 24, 2023
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
6 changes: 3 additions & 3 deletions src/featureinfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -601,8 +601,8 @@ const Featureinfo = function Featureinfo(options = {}) {
};

/**
* Shows the featureinfo popup/sidebar/infowindow for the provided feature and fit the view to it.
* @param {any} featureObj An object containing layerName and feature
* Shows the featureinfo popup/sidebar/infowindow for the provided features and fit the view to it.
* @param {any} featureObj An object containing layerName and feature. "feature" is either one Feature or an Array of Feature
* @param {any} opts An object containing options. Supported options are : coordinate, the coordinate where popup will be shown. If omitted first feature is used.
* ignorePan, do not autopan if type is overlay. Pan should be supressed if view is changed manually to avoid contradicting animations.
* @returns nothing
Expand All @@ -624,7 +624,7 @@ const Featureinfo = function Featureinfo(options = {}) {
}
if (newItems.length > 0) {
render(newItems, identifyTarget, opts.coordinate || maputils.getCenter(newItems[0].getFeature().getGeometry()), opts);
viewer.getMap().getView().fit(maputils.getExtent(featureObj.feature));
viewer.getMap().getView().fit(maputils.getExtent(newItems.map(i => i.getFeature())));
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/layer/agsfeature.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function createSource({
const esrijsonFormat = new EsriJSON();
const vectorSource = new VectorSource({
attributions: attribution,
loader(extent, resolution, projection) {
loader(extent, resolution, projection, success) {
const that = this;
let url = sourceUrl.endsWith('/') ? sourceUrl : `${sourceUrl}/`;
url += id
Expand All @@ -40,6 +40,7 @@ function createSource({
if (features.length > 0) {
that.addFeatures(features);
}
success(features);
}).catch(error => console.warn(error));
},
strategy: loadingstrategy.bbox
Expand Down
3 changes: 2 additions & 1 deletion src/layer/geojson.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function createSource(options) {
if (options.url) {
const vectorSource = new VectorSource({
attributions: options.attribution,
loader() {
loader(extent, resolution, projection, success) {
fetch(options.url, { headers: options.headers }).then(response => response.json()).then((data) => {
if (data.features) {
vectorSource.addFeatures(vectorSource.getFormat().readFeatures(data, formatOptions));
Expand All @@ -34,6 +34,7 @@ function createSource(options) {
});
}
}
success(vectorSource.getFeatures());
}).catch(error => console.warn(error));
},
format: new GeoJSON()
Expand Down
4 changes: 4 additions & 0 deletions src/maputils.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ const maputils = {
}
return center;
},
/**
* Gets the union extent for an array of features
* @param {any} featureArray An array of features
*/
getExtent: function getCenter(featureArray) {
const featureExtent = featureArray[0].getGeometry().getExtent();
let i;
Expand Down
97 changes: 55 additions & 42 deletions src/viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,26 @@ const Viewer = function Viewer(targetOption, options = {}) {
return urlParams;
};

/**
* Internal helper used when urlParams.feature is set and the popup should be displayed.
* @param {any} feature
* @param {any} layerName
*/
const displayFeatureInfo = function displayFeatureInfo(feature, layerName) {
if (feature) {
const fidsbylayer = {};
fidsbylayer[layerName] = [feature.getId()];
featureinfo.showInfo(fidsbylayer, { ignorePan: true });
if (!urlParams.zoom && !urlParams.center) {
map.getView().fit(feature.getGeometry(), {
maxZoom: getResolutions().length - 2,
padding: [15, 15, 40, 15],
duration: 1000
});
}
}
};

return Component({
onInit() {
this.render();
Expand Down Expand Up @@ -577,50 +597,43 @@ const Viewer = function Viewer(targetOption, options = {}) {
const layer = getLayer(layerName);
if (layer && layer.get('type') !== 'GROUP') {
const layerType = layer.get('type');
// FIXME: postrender event is only emitted if any features from a layer is actually drawn, which means there is no feature in the default extent,
// it will not be triggered until map is panned or zoomed where a feature exists.
layer.once('postrender', () => {
const clusterSource = layer.getSource().source;
// Assume that id is just the second part of the argumment and adjust it for special cases later.
let id = featureId.split('.')[1];
let feature;

if (layerType === 'WFS') {
// WFS uses the layername as a part of the featureId. Problem is that it what the server think is the name that matters.
// First we assume that the layername is actually correct, then take the special cases
let idLayerPart = layerName;
const layerId = layer.get('id');
if (layerId) {
// if layer explicitly has set the id it takes precedense over name
// layer name already have popped the namespace part, but id is untouched.
idLayerPart = layerId.split(':').pop();
} else if (layerName.includes('__')) {
// If using the __-notation to use same layer several times, we must only use the actual layer name
idLayerPart = layerName.split('__')[0];
}
// Build the correct WFS id
id = `${idLayerPart}.${id}`;
}
// FIXME: ensure that feature is loaded. If using bbox and feature is outside default extent it will not be found.
// Workaround is to have a default extent covering the entire map with the layer in visible range or use strategy all
if (clusterSource) {
feature = clusterSource.getFeatureById(id);
} else {
feature = layer.getSource().getFeatureById(id);
const layerSource = layer.getSource().source ? layer.getSource().source : layer.getSource();
// Assume that id is just the second part of the argumment and adjust it for special cases later.
let id = featureId.split('.')[1];

if (layerType === 'WFS') {
// WFS uses the layername as a part of the featureId. Problem is that it what the server think is the name that matters.
// First we assume that the layername is actually correct, then take the special cases
let idLayerPart = layerName;
const layerId = layer.get('id');
if (layerId) {
// if layer explicitly has set the id it takes precedense over name
// layer name already have popped the namespace part, but id is untouched.
idLayerPart = layerId.split(':').pop();
} else if (layerName.includes('__')) {
// If using the __-notation to use same layer several times, we must only use the actual layer name
idLayerPart = layerName.split('__')[0];
}
// Build the correct WFS id
id = `${idLayerPart}.${id}`;
}

if (feature) {
const obj = {};
obj.feature = feature;
obj.layerName = layerName;
featureinfo.showFeatureInfo(obj);
map.getView().fit(feature.getGeometry(), {
maxZoom: getResolutions().length - 2,
padding: [15, 15, 40, 15],
duration: 1000
});
}
});
// Some layer types may already have been loaded, e.g. GeoJson with static configured features. As features are loaded
// on creation it is impossible to listen to the featuresloadend event, but on the other hand the features will be ready already
// when we get here. It is highly unlikely that a remote source is finished already, but that would work as well.
if (layerSource.getFeatures().length > 0) {
displayFeatureInfo(layerSource.getFeatureById(id), layerName);
} else {
// Set up an eventhandler and wait for the source to finsish loading if there are no features yet.
// Important that the source actually emits this event.
layerSource.once('featuresloadend', () => {
// FIXME: ensure that feature is loaded. If using bbox and feature is outside default extent it will not be found.
// Workaround is to have a default extent covering the entire map with the layer in visible range or use strategy all
// Most likely it will work as sharemap links contains center and zoom so extent will be visible. Most sane people
// will only share maps where the selected feature is in view
displayFeatureInfo(layerSource.getFeatureById(id), layerName);
});
}
}
}

Expand Down
Loading