Skip to content

Instantly share code, notes, and snippets.

@xemoka
Last active June 1, 2020 14:10
Show Gist options
  • Save xemoka/cb4cf95018fdc2cebac4da8f0c308723 to your computer and use it in GitHub Desktop.
Save xemoka/cb4cf95018fdc2cebac4da8f0c308723 to your computer and use it in GitHub Desktop.
infoClickHandler
function infoClickHandler (event) {
console.log('Info Click Handler Fired:', event)
let currentInfos = [] // the array we'll fill with the data returned from arcgis Server
// get pixel click location
const pixel = mapElement.getEventPixel(event.originalEvent)
// generate list of layers
let layers = []
mapELement.forEachLayerAtPixel(
pixel,
layer => {
layers.push(layer)
},
{
layerFilter: layer => {
return (
layer.get('ignoreInfo') !== true && // give your non-infoable layers a property to filter by, when creating the OpenLayersObject for the layer, make sure you `layer.set('ignoreInfo', true)`
!(layer instanceof VectorTileLayer) && // only if the layer is not a vector layer do we want to query
!(layer instanceof VectorLayer) // the ${mapServer}/identify endpoint;
)
},
hitTolerance: 0
}
)
// only if there are layers to query
if ( layers.length > 0 ) {
const clickCoordinate = mapElement.getCoordinateFromPixel(pixel)
let mapServerInfo = []
layers
.forEach(layer => {
const url = layer.getSource().getUrl() // collect mapServer URL
const id = layer
.getSource()
.getParams()
.layers.replace('show:', '') // remove the visible component to just get the raw url
const server = mapServerInfo.find(server => server.url === url) // see if server already exists in mapServerInfo
if (!server) {
mapServerInfo.push({ url: url, layers: [id] }) // if not, add it
} else {
mapServerInfo.find(server => server.url === url).layers.push(id) // if so, add the ID of this layer for query
}
})
console.log('Request for:', layers.map(layer => layer.get('name'))) // 'name' property is one I assign with layer.set('name', ${name})
const requestUrls = mapServerInfo.map(server => { // for each mapServer, build a query object and add it to an array
const query = {
geometry: clickCoordinate, // where in CRS we clicked
geometryType: 'esriGeometryPoint',
sr: 3857,
layers: `all:${server.layers}`, // query all the layer ids for htis map server built above
tolerance: 5,
mapExtent: mapElement.getView().calculateExtent(), // get map extent
imageDisplay: `${mapElement.getSize()},72`, // get map size/resolution
returnGeometry: false, // I don't want geometry, but you might want to display it on a 'selection layer'
f: 'json'
}
const url = new URL(`${server.url}/identify`)
url.search = new URLSearchParams(query)
return url
})
Promise.all(requestUrls.map(url => fetch(url))) // build a promise, fetch the data using the fetchAPI
.then(responses =>
Promise.all(responses.map(response => response.json())) // unwrap the response
)
.then(response => {
let mergedResponses = [] // merge them together
response.forEach(result => mergedResponses.push(...result.results))
currentInfos.push(...mergedResponses)
})
}
console.log(currentInfos) // do with these as you would, like throw them in a popup.
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment