From 88bfeb9724f0a6f2e98be6b5ca016cb0f30c568a Mon Sep 17 00:00:00 2001 From: Vijayan Balasubramanian Date: Mon, 6 Feb 2023 14:42:24 -0800 Subject: [PATCH] Fix popup display while zoomed out (#226) * Update tool tip condition * Clean up code Signed-off-by: Vijayan Balasubramanian --- .../layer_control_panel.tsx | 8 ++---- .../map_container/map_container.tsx | 15 ++++++++--- public/components/tooltip/create_tooltip.tsx | 27 ++++++++++++------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/public/components/layer_control_panel/layer_control_panel.tsx b/public/components/layer_control_panel/layer_control_panel.tsx index 310ecd91..e77a8b26 100644 --- a/public/components/layer_control_panel/layer_control_panel.tsx +++ b/public/components/layer_control_panel/layer_control_panel.tsx @@ -35,11 +35,7 @@ import { LAYER_PANEL_SHOW_LAYER_ICON, LAYER_VISIBILITY, } from '../../../common'; -import { - LayerActions, - layersFunctionMap, - referenceLayerTypeLookup, -} from '../../model/layersFunctions'; +import { referenceLayerTypeLookup } from '../../model/layersFunctions'; import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public'; import { MapServices } from '../../types'; import { @@ -48,7 +44,7 @@ import { } from '../../model/layerRenderController'; import { MapState } from '../../model/mapState'; import { ConfigSchema } from '../../../common/config'; -import {moveLayers, removeLayers, updateLayerVisibility} from "../../model/map/layer_operations"; +import { moveLayers, removeLayers, updateLayerVisibility } from '../../model/map/layer_operations'; interface MaplibreRef { current: Maplibre | null; diff --git a/public/components/map_container/map_container.tsx b/public/components/map_container/map_container.tsx index 3f215365..3d833e5d 100644 --- a/public/components/map_container/map_container.tsx +++ b/public/components/map_container/map_container.tsx @@ -13,7 +13,7 @@ import { MAP_INITIAL_STATE, DASHBOARDS_MAPS_LAYER_TYPE } from '../../../common'; import { MapLayerSpecification } from '../../model/mapLayerType'; import { IndexPattern } from '../../../../../src/plugins/data/public'; import { MapState } from '../../model/mapState'; -import { createPopup, getPopupLngLat, isTooltipEnabledLayer } from '../tooltip/create_tooltip'; +import { createPopup, getPopupLocation, isTooltipEnabledLayer } from '../tooltip/create_tooltip'; import { handleDataLayerRender } from '../../model/layerRenderController'; import { useOpenSearchDashboards } from '../../../../../src/plugins/opensearch_dashboards_react/public'; import { MapServices } from '../../types'; @@ -86,12 +86,13 @@ export const MapContainer = ({ if (features && maplibreRef.current) { clickPopup = createPopup({ features, layers: tooltipEnabledLayers }); clickPopup - ?.setLngLat(getPopupLngLat(features[0].geometry) ?? e.lngLat) + ?.setLngLat(getPopupLocation(features[0].geometry, e.lngLat)) .addTo(maplibreRef.current); } } function onMouseMoveMap(e: MapEventType['mousemove']) { + // This is required to update coordinates on map only on mouse move setCoordinates(e.lngLat.wrap()); // remove previous popup @@ -107,7 +108,7 @@ export const MapContainer = ({ showLayerSelection: false, }); hoverPopup - ?.setLngLat(getPopupLngLat(features[0].geometry) ?? e.lngLat) + ?.setLngLat(getPopupLocation(features[0].geometry, e.lngLat)) .addTo(maplibreRef.current); } } @@ -166,7 +167,13 @@ export const MapContainer = ({ return (
- + {coordinates && `lat: ${coordinates.lat.toFixed(4)}, lon: ${coordinates.lng.toFixed(4)}, `} diff --git a/public/components/tooltip/create_tooltip.tsx b/public/components/tooltip/create_tooltip.tsx index 7d86fc66..d7c019d3 100644 --- a/public/components/tooltip/create_tooltip.tsx +++ b/public/components/tooltip/create_tooltip.tsx @@ -1,17 +1,18 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Popup, MapGeoJSONFeature } from 'maplibre-gl'; +import { Popup, MapGeoJSONFeature, LngLat } from 'maplibre-gl'; import { MapLayerSpecification, DocumentLayerSpecification } from '../../model/mapLayerType'; import { FeatureGroupItem, TooltipContainer } from './tooltipContainer'; +import {MAX_LONGITUDE} from "../../../common"; -type Options = { +interface Options { features: MapGeoJSONFeature[]; layers: DocumentLayerSpecification[]; showCloseButton?: boolean; showPagination?: boolean; showLayerSelection?: boolean; -}; +} export function isTooltipEnabledLayer( layer: MapLayerSpecification @@ -19,7 +20,8 @@ export function isTooltipEnabledLayer( return ( layer.type !== 'opensearch_vector_tile_map' && layer.type !== 'custom_map' && - layer.source.showTooltips === true + layer.source.showTooltips === true && + !!layer.source.tooltipFields?.length ); } @@ -39,15 +41,22 @@ export function groupFeaturesByLayers( return featureGroups; } -export function getPopupLngLat(geometry: GeoJSON.Geometry) { +export function getPopupLocation(geometry: GeoJSON.Geometry, mousePoint: LngLat) { // geometry.coordinates is different for different geometry.type, here we use the geometry.coordinates // of a Point as the position of the popup. For other types, such as Polygon, MultiPolygon, etc, // use mouse position should be better - if (geometry.type === 'Point') { - return [geometry.coordinates[0], geometry.coordinates[1]] as [number, number]; - } else { - return null; + if (geometry.type !== 'Point') { + return mousePoint; + } + const coordinates = geometry.coordinates; + // Copied from https://maplibre.org/maplibre-gl-js-docs/example/popup-on-click/ + // Ensure that if the map is zoomed out such that multiple + // copies of the feature are visible, the popup appears + // over the copy being pointed to. + while (Math.abs(mousePoint.lng - coordinates[0]) > MAX_LONGITUDE) { + coordinates[0] += mousePoint.lng > coordinates[0] ? 360 : -360; } + return [coordinates[0], coordinates[1]] as [number, number]; } export function createPopup({