Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

Commit

Permalink
Merge pull request #357 from Bayer-Group/Raster-pixel-identification
Browse files Browse the repository at this point in the history
Identify pixel value on click
  • Loading branch information
stazrad authored Nov 16, 2021
2 parents e7d1421 + 4e31252 commit 415ffdd
Show file tree
Hide file tree
Showing 195 changed files with 617 additions and 350 deletions.
2 changes: 1 addition & 1 deletion docs/BasemapBingMaps.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapBlankWhite.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapContainer.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapManager.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapOpenStreetMap.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapStamenTerrain.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapStamenTonerDark.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/BasemapStamenTonerLite.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_BasemapContainer.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_BasemapManager.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_BingMaps.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_BlankWhite.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_OpenStreetMap.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_StamenTerrain.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_StamenTonerDark.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_StamenTonerLite.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Basemaps_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Compass.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenu.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenuCoords.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenuListItem.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenu_ContextMenu.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenu_ContextMenuCoords.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ContextMenu_ContextMenuListItem.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ControlGroup.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ControlGroupButton.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_Compass.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ControlGroup.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ControlGroupButton.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_Controls.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_CurrentLocation.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ScaleLine.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ZoomControls.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ZoomIn.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Controls_ZoomOut.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/CurrentLocation.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DataLayers_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawBox.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawCircle.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawContainer.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawFreehand.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawLine.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawPin.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawPoint.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/DrawPolygon.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Box.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Circle.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Draw.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_DrawContainer.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Freehand.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Line.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Pin.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Point.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_Polygon.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Draw_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/FeatureEditor.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/FeatureEditor_FeatureEditor.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/FeatureEditor_styles.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/GoogleDirections.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/GoogleDirections_GoogleDirections.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/GooglePlacesSearch.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/GooglePlacesSearch_GooglePlacesSearch.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/HeatmapControls.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Heatmap_HeatmapControls.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ImageExif_ImageExif.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionDuplicate.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionExport.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionExtent.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionHeatmap.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionImport.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionMerge.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionMergeFeatures.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionOpacity.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActionRemove.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelActions.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelBase.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelCheckbox.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelContent.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelHeader.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelLayersPage.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelList.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelListItem.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelMenu.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanelPage.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanel.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionDuplicate_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionExport_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionExport_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionExtent_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionHeatmap_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionHeatmap_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionImport_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionImport_utils.js.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionMerge_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionMerge_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionOpacity_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActionRemove_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelActions_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelBase_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelCheckbox_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelContent_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelHeader_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelLayersPage_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelListItem_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelList_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelMenu_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerPanel_LayerPanelPage_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler_LayerStyler.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler_StyleManager_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__AttributesFilter_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__ColorPicker_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__LabelStyler_index.js.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__LayerStyler__StyleGroup_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__LayerStyler_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__Popover_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__SelectTabs_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/LayerStyler__Selector_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Map.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Map_Map.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Map_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Measure_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/MultiMapManager.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/MultiMapManager_MultiMapManager.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/MultiMapManager_SafeParent.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/MultiMapManager_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Pdf_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/PopupActionCopyWkt.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/PopupActionGoogleMaps.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupActionGroup.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupActionItem.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupActionLink.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/PopupBase.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupDataList.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/PopupDefaultInsert.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupDefaultPage.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupPageLayout.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupPageLayoutChild.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/PopupTabs.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_Popup.js.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupActions_PopupActionCopyWkt_utils.js.html

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupBase.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupActionGroup_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupActionItem_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupActionLink_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupDataList_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupDefaultInsert.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupDefaultPage_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupPageLayoutChild_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupPageLayout_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert_PopupTabs_index.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Popup_PopupInsert__LoadingSpinner_index.js.html

Large diffs are not rendered by default.

86 changes: 59 additions & 27 deletions docs/Popup_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ProjectMenu.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Project_Project.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Project_utils.js.html

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions docs/Provider.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Provider_Provider.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Provider_utils.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TabbedPanel.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TabbedPanel_TabbedPanel.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TimeSlider.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TimeSliderBase.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TimeSlider_TimeSlider.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/TimeSlider_TimeSliderBase.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/Toolbar_Toolbar.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ZoomControls.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ZoomIn.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/ZoomOut.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/classes_VectorLayer.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/classes_VectorTileLayer.js.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/docs.html

Large diffs are not rendered by default.

216 changes: 208 additions & 8 deletions docs/global.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-Getting Started.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-LayerPanel_.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-Popup_.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-TimeSlider_.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-connectToContext.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-contextProps.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/tutorial-i18n Support.html

Large diffs are not rendered by default.

228 changes: 131 additions & 97 deletions src/Popup/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,42 @@ import GeoJSON from 'ol/format/GeoJSON'
import olLayerVector from 'ol/layer/Vector'
import olVectorTile from 'ol/layer/VectorTile'
import olSourceCluster from 'ol/source/Cluster'
import olFeature from 'ol/Feature'
import olGeomPoint from 'ol/geom/Point'
import debounce from 'lodash.debounce'
import ugh from 'ugh'

/**
* Creates a new feature with point geometry at the location of the pixel and attributes describing the pixel's value
* @function
* @category Popup
* @since 1.17.0
* @param {ol.Layer} layer - The openlayers layer
* @param {Object} event - An object with a `map` and `pixel` property
* @returns {ol.Feature} An openlayers feature with point geometry at the location of the pixel and attributes describing the pixel's value
*/
export const getPixelValue = (layer, event) => {
const { map, pixel } = event
const clickCoordinate = map.getCoordinateFromPixel(pixel)

let renderedLayer = layer

if (layer.isGeoserverLayer) renderedLayer = layer.getWMSLayer()

const renderContext = renderedLayer.getRenderer().context
const pixelImageData = renderContext.getImageData(pixel[0], pixel[1], 1, 1)
const [red, green, blue, alpha] = pixelImageData.data

return new olFeature({
geometry: new olGeomPoint(clickCoordinate),
title: layer.getProperties().title || 'Raster Pixel',
red,
green,
blue,
alpha
})
}

/**
* Bind multiple move listeners with the same callback
* @function
Expand Down Expand Up @@ -41,137 +74,138 @@ export const addMovementListener = (map, callback) => {
* @category Popup
* @since 0.2.0
* @param {ol.Map} map - The openlayers map to which the events are bound
* @param {Array} keys - remove the listeners via an array of event keys
* @param {Array} keys - remove the listeners via` an array of event keys
*/
export const removeMovementListener = (keys = []) => {
keys.forEach(({ target, type, listener }) => target.un(type, listener))
}

/**
* Get all features for a given click event
* @function
* @category Popup
* @since 0.2.0
* @param {Object} event - An object with an `event` and `pixel` property
* @param {ol.Map} event.map - The openlayers map where the layer exists
* @param {Number[]} event.pixel - An array consisting of `x` and `y` pixel locations
* @param {Object} [opts] - Object of optional params
* @param {Number} [opts.hitTolerance = 3] - Additional area around features that is clickable to select them
* @returns {Promise[]} An array of promises, each of which resolve to an object `{ layer, features }`
*/
export const getLayersAndFeaturesForEvent = (event, opts = {}) => {
if (typeof event !== 'object') return ugh.error('getLayersAndFeaturesForEvent first arg must be an object') // eslint-disable-line
const { map, pixel } = event
const promises = []
const clickCoordinate = map.getCoordinateFromPixel(pixel)
const setParentLayer = ({ features, layer }) => {
return new Promise(resolve => {
const parentLayer = layer.get('_ol_kit_parent')
const parent = parentLayer || layer

if (!(map instanceof olMap) || !Array.isArray(pixel)) return ugh.error('getLayersAndFeaturesForEvent requires a valid openlayers map & pixel location (as an array)') // eslint-disable-line

const setParentLayer = ({ features, layer }) => {
return new Promise(resolve => {
const parentLayer = layer.get('_ol_kit_parent')
const parent = parentLayer || layer

features.forEach((feature, i) => {
// true makes this performant with a silent trigger: https://openlayers.org/en/latest/apidoc/module-ol_Feature.html#set
feature.set('_ol_kit_parent', parent, true)

return feature
})
features.forEach((feature, i) => {
// true makes this performant with a silent trigger: https://openlayers.org/en/latest/apidoc/module-ol_Feature.html#set
feature.set('_ol_kit_parent', parent, true)

resolve({ features, layer })
return feature
})
}

const wfsSelector = layer => {
// this logic only handles clicks on vector layer types
const allowedLayerType = layer.isVectorLayer || layer instanceof olLayerVector
resolve({ features, layer })
})
}

// layer.getLayerState().managed is an undocumented ol prop that lets us ignore select's vector layer
if (!layer.getLayerState().managed || !allowedLayerType) return // do nothing with these layer types
const wfsSelector = (layer, event, opts) => {
let features = []
const source = layer.getSource()
const { map, pixel } = event
const clickCoordinate = map.getCoordinateFromPixel(pixel)
// check for featuresAtPixel to account for hitTolerance
const featuresAtPixel = map.getFeaturesAtPixel(pixel, {
layerFilter: () => true,
hitTolerance: opts.hitTolerance ? opts.hitTolerance : 3,
checkWrapped: true
})

let features = []
const source = layer.getSource()
if (source instanceof olSourceCluster) {
// support for clustered feature clicks
const clusteredFeatures = source.getClosestFeatureToCoordinate(clickCoordinate).get('features')

if (source instanceof olSourceCluster) {
// support for clustered feature clicks
const clusteredFeatures = source.getClosestFeatureToCoordinate(clickCoordinate).get('features')
features = clusteredFeatures
} else {
const sourceFeatures = source.getFeatures()

features = clusteredFeatures
} else {
const sourceFeatures = source.getFeatures()
sourceFeatures.forEach(sourceFeature => {
// check if any feature on layer source is also at click location
const isAtPixel = featuresAtPixel ? featuresAtPixel.find(f => f === sourceFeature) : null

sourceFeatures.forEach(sourceFeature => {
// check if any feature on layer source is also at click location
const isAtPixel = featuresAtPixel ? featuresAtPixel.find(f => f === sourceFeature) : null
if (isAtPixel) features.push(sourceFeature)
})
}

if (isAtPixel) features.push(sourceFeature)
})
}
if (features.length) return setParentLayer({ features, layer })
}

if (features.length) {
const wfsPromise = setParentLayer({ features, layer })
const wmsSelector = (layer, event) => {
const { pixel, map } = event
const coords = map.getCoordinateFromPixel(pixel)

promises.push(wfsPromise)
}
}
const wmsSelector = layer => {
if (layer.get('_ol_kit_parent')?.isGeoserverLayer) {
// this logic handles clicks on GeoserverLayers
const geoserverLayer = layer.get('_ol_kit_parent')
const coords = map.getCoordinateFromPixel(pixel)
const wmsPromise = new Promise(async resolve => { // eslint-disable-line no-async-promise-executor
const rawFeatures = await geoserverLayer.fetchFeaturesAtClick(coords, map)
const { features } = await setParentLayer({ features: rawFeatures, layer })

resolve({ features, layer })
})
return new Promise(async resolve => { // eslint-disable-line no-async-promise-executor
const rawFeatures = await layer.fetchFeaturesAtClick(coords, map)
const { features } = await setParentLayer({ features: rawFeatures, layer })

promises.push(wmsPromise)
if (features.length) {
resolve({ features, layer })
} else {
resolve({ features: [getPixelValue(layer, event)], layer })
}
}
})
}

const vectorTileSelector = (layer, event, opts) => {
const { map, pixel } = event
// check for featuresAtPixel to account for hitTolerance
const featuresAtPixel = map.getFeaturesAtPixel(pixel, {
layerFilter: () => true,
hitTolerance: opts.hitTolerance ? opts.hitTolerance : 3,
checkWrapped: true
})

// if there's features at click, loop through the layers to find corresponding layer & features
if (featuresAtPixel?.length) {
map.getLayers().forEach(async layer => {
if (layer instanceof olVectorTile) {
const vectorTilePromise = new Promise(async resolve => { // eslint-disable-line no-async-promise-executor
const vectorTileSourceFeatures = await layer.getSource()
.getFeaturesInExtent(map.getView().calculateExtent(map.getSize()))
const matchingFeaturesAtPixel = vectorTileSourceFeatures.filter(sourceFeature => {
const { ol_uid } = sourceFeature // eslint-disable-line camelcase
return new Promise(async resolve => { // eslint-disable-line no-async-promise-executor
const vectorTileSourceFeatures = await layer.getSource()
.getFeaturesInExtent(map.getView().calculateExtent(map.getSize()))
const matchingFeaturesAtPixel = vectorTileSourceFeatures.filter(sourceFeature => {
const { ol_uid } = sourceFeature // eslint-disable-line camelcase

let isFeatureAtClick = false

let isFeatureAtClick = false
featuresAtPixel.forEach(feat => {
if (feat?.ol_uid === ol_uid) isFeatureAtClick = true // eslint-disable-line camelcase
})

return isFeatureAtClick
})

featuresAtPixel.forEach(feat => {
if (feat?.ol_uid === ol_uid) isFeatureAtClick = true // eslint-disable-line camelcase
})
const { features } = await setParentLayer({ features: matchingFeaturesAtPixel, layer })

return isFeatureAtClick
})
resolve({ features, layer })
})
}

const { features } = await setParentLayer({ features: matchingFeaturesAtPixel, layer })
/**
* Get all features for a given click event
* @function
* @category Popup
* @since 0.2.0
* @param {Object} event - An object with a `map` and `pixel` property
* @param {ol.Map} event.map - The openlayers map where the layer exists
* @param {Number[]} event.pixel - An array consisting of `x` and `y` pixel locations
* @param {Object} [opts] - Object of optional params
* @param {Number} [opts.hitTolerance = 3] - Additional area around features that is clickable to select them
* @returns {Promise[]} An array of promises, each of which resolve to an object `{ layer, features }`
*/
export const getLayersAndFeaturesForEvent = (event, opts = {}) => {
if (typeof event !== 'object') return ugh.error('getLayersAndFeaturesForEvent first arg must be an object') // eslint-disable-line
const { map, pixel } = event

resolve({ features, layer })
})
if (!(map instanceof olMap) || !Array.isArray(pixel)) return ugh.error('getLayersAndFeaturesForEvent requires a valid openlayers map & pixel location (as an array)') // eslint-disable-line

promises.push(vectorTilePromise)
} else {
const promises = map.getLayers().getArray().map(layer => {
if (layer instanceof olVectorTile) {
// handle vector tile features
return vectorTileSelector(layer, event, opts)
} else if (layer.isVectorLayer || layer instanceof olLayerVector || !layer.getLayerState().managed) { // layer.getLayerState().managed is an undocumented ol prop that lets us ignore select's vector layer
// handle non vector tile wfs layers
wfsSelector(layer)
}
})
}

// this check is for wms features
map.forEachLayerAtPixel(pixel, wmsSelector)
return wfsSelector(layer, event, opts)
} else if (layer.isGeoserverLayer) {
// handle geoserver layers
return wmsSelector(layer, event)
} else if (!layer.getProperties()._ol_kit_basemap) {
// get the pixel value for any other non-basemap layers
return { features: [getPixelValue(layer, event)] }
}
}).filter(Boolean)

return promises
}
Expand Down
1 change: 1 addition & 0 deletions src/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ Object {
"exportFeatures": [Function],
"getExtentForFeatures": [Function],
"getLayersAndFeaturesForEvent": [Function],
"getPixelValue": [Function],
"getPopupPositionFromFeatures": [Function],
"getSelectInteraction": [Function],
"getStyledFeatures": [Function],
Expand Down

0 comments on commit 415ffdd

Please sign in to comment.