UNPKG

react-mapfilter

Version:

These components are designed for viewing data in Mapeo. They share a common interface:

180 lines (165 loc) 4.88 kB
import _extends from "@babel/runtime-corejs3/helpers/extends"; import _reduceInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reduce"; import _Object$assign from "@babel/runtime-corejs3/core-js-stable/object/assign"; // @flow import React, { useMemo, useCallback, useContext, useRef } from 'react'; import { Layer, Source, MapContext } from 'react-mapbox-gl'; /*:: import type { Observation } from 'mapeo-schema'*/ /*:: import type { Point2D, FeatureTemplate, FeatureCollectionTemplate } from 'flow-geojson'*/ /*:: type Props = { observations: Array<Observation>, onMouseMove: any => any, onMouseLeave: any => any, onClick?: (id: string) => any, print?: boolean }*/ /*:: type FeaturePoint2D = FeatureTemplate<Point2D>*/ /*:: type FeatureCollectionPoint2D = FeatureCollectionTemplate<FeaturePoint2D[]>*/ /*:: type GeoJsonSource = { type: 'geojson', data: FeatureCollectionPoint2D }*/ const observationSourceId = 'mapeo-observations-internal'; // const labelStyleLayer = { // id: 'labels', // type: 'symbol', // source: 'features', // layout: { // 'text-field': '', // 'text-allow-overlap': true, // 'text-ignore-placement': true, // 'text-size': 9, // 'text-font': ['DIN Offc Pro Bold', 'Arial Unicode MS Bold'] // }, // paint: { // 'text-color': '#fff', // 'text-halo-color': 'rgba(100,100,100, 0.3)', // 'text-halo-width': 0.3 // } // } const pointStyleLayer = { id: 'points', type: 'circle', sourceId: observationSourceId, paint: { // make circles larger as the user zooms from z12 to z22 'circle-radius': { base: 1.5, stops: [[7, 5], [18, 25]] }, 'circle-color': '#ff0000', 'circle-opacity': 0.75, 'circle-stroke-width': 1.5, 'circle-stroke-color': '#ffffff', 'circle-stroke-opacity': 0.9 } }; const pointHoverStyleLayer = { id: 'points-hover', type: 'circle', sourceId: observationSourceId, paint: _Object$assign({}, pointStyleLayer.paint, { 'circle-opacity': ['case', ['boolean', ['feature-state', 'hover'], false], 1, 0], 'circle-stroke-width': 2.5, 'circle-stroke-color': '#ffffff', 'circle-stroke-opacity': ['case', ['boolean', ['feature-state', 'hover'], false], 1, 0] }) }; function observationsToGeoJsonSource(observations /*: Observation[]*/ ) /*: GeoJsonSource*/ { return { type: 'geojson', data: { type: 'FeatureCollection', features: _reduceInstanceProperty(observations).call(observations, (acc, obs, i) => { // Skip if null or undefined if (obs.lat == null || obs.lon == null) return acc; const point /*: FeaturePoint2D*/ = { id: i, type: 'Feature', geometry: { type: 'Point', coordinates: [obs.lon, obs.lat] }, properties: { id: obs.id } }; acc.push(point); return acc; }, []) } }; } const noop = () => {}; const ObservationLayer = ({ observations, onClick = noop, onMouseLeave, onMouseMove, print = false } /*: Props*/ ) => { const hovered = useRef(null); const map = useContext(MapContext); const geoJsonSource = useMemo(() => observationsToGeoJsonSource(observations), [observations]); const handleMouseMove = useCallback(e => { if (print) return; map.getCanvas().style.cursor = e.features.length ? 'pointer' : ''; if (e.features.length === 0) return; if (hovered.current) { map.setFeatureState({ source: observationSourceId, id: hovered.current }, { hover: false }); } hovered.current = e.features[0].id; map.setFeatureState({ source: observationSourceId, id: hovered.current }, { hover: true }); onMouseMove(e); }, [map, onMouseMove, print]); const handleMouseLeave = useCallback(e => { if (print) return; if (hovered.current) { map.setFeatureState({ source: observationSourceId, id: hovered.current }, { hover: false }); } hovered.current = null; map.getCanvas().style.cursor = ''; onMouseLeave(e); }, [map, onMouseLeave, print]); const handleClick = useCallback(e => { if (print) return; if (e.features.length === 0) return; onClick(e.features[0].properties.id); }, [onClick, print]); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Source, { id: observationSourceId, geoJsonSource: geoJsonSource }), /*#__PURE__*/React.createElement(Layer, _extends({}, pointStyleLayer, { onClick: handleClick, onMouseMove: handleMouseMove, onMouseLeave: handleMouseLeave })), /*#__PURE__*/React.createElement(Layer, pointHoverStyleLayer)); }; export default ObservationLayer; //# sourceMappingURL=ObservationLayer.js.map