Skip to content

Commit

Permalink
CDC #248 - Creating separate components for react-map-gl and @periple…
Browse files Browse the repository at this point in the history
…o/maplibre warped layer components
  • Loading branch information
dleadbetter committed Jul 22, 2024
1 parent 3ce619c commit 4dd6f0f
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 51 deletions.
2 changes: 1 addition & 1 deletion packages/core-data/src/components/OverlayLayers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

import { MapStyles, WarpedImageLayer } from '@performant-software/geospatial';
import { MapStyles, WarpedImageLayerPeripleo as WarpedImageLayer } from '@performant-software/geospatial';
import { GeoJSONLayer, RasterLayer } from '@peripleo/maplibre';
import React from 'react';
import _ from 'underscore';
Expand Down
4 changes: 3 additions & 1 deletion packages/geospatial/src/components/LayerMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import React, {
Children,
useCallback,
useEffect,
useMemo, useRef,
useMemo,
useRef,
useState
} from 'react';
import { BsStack } from 'react-icons/bs';
Expand Down Expand Up @@ -103,6 +104,7 @@ const LayerMenu = (props: Props) => {
position={props.position}
>
<button
aria-label='Toggle Menu'
className='mapbox-gl-draw_ctrl-draw-btn layer-button'
onClick={() => setMenuOpen((prevMenuOpen) => !prevMenuOpen)}
type='button'
Expand Down
40 changes: 20 additions & 20 deletions packages/geospatial/src/components/WarpedImageLayer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// @flow

import { WarpedMapLayer } from '@allmaps/maplibre';
import { useLoadedMap } from '@peripleo/maplibre';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useMap } from 'react-map-gl';
import MapUtils from '../utils/Map';

type Props = {
/**
Expand All @@ -27,33 +27,33 @@ type Props = {
};

const WarpedImageLayer = (props: Props) => {
const map = useLoadedMap();
const [loaded, setLoaded] = useState(false);

const mapRef = useMap();

useEffect(() => {
const instance = mapRef?.current?.getMap();
instance.on('load', () => setLoaded(true));
}, []);

/**
* Adds the WarpedMapLayer object to the map as a new layer.
*/
useEffect(() => {
if (!map) {
if (!loaded) {
return undefined;
}

const warpedMapLayer = new WarpedMapLayer(props.id);
map.addLayer(warpedMapLayer);

if (props.url) {
warpedMapLayer.addGeoreferenceAnnotationByUrl(props.url);
} else if (props.manifest) {
warpedMapLayer.addGeoreferenceAnnotation(props.manifest);
}
const map = mapRef.current.getMap();

warpedMapLayer.setOpacity(props.opacity);
MapUtils.addGeoreferenceLayer(map, props.id, {
manifest: props.manifest,
opacity: props.opacity,
url: props.url
});

return () => {
if (map) {
map.removeLayer(props.id);
}
};
}, [map]);
return () => MapUtils.removeLayer(map, props.id);
}, [loaded]);

return null;
};
Expand Down
56 changes: 56 additions & 0 deletions packages/geospatial/src/components/WarpedImageLayerPeripleo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @flow

import { useEffect } from 'react';
import { useLoadedMap } from '@peripleo/maplibre';
import MapUtils from '../utils/Map';

type Props = {
/**
* ID of the new layer.
*/
id: string,

/**
* (Optional) IIIF manifest content containing the image and geo-reference annotations.
*/
manifest?: string,

/**
* (Optional) layer opacity.
*/
opacity?: number,

/**
* (Optional) URL to the IIIF manifest.
*/
url?: string
};

const WarpedImageLayer = (props: Props) => {
const map = useLoadedMap();

/**
* Adds the WarpedMapLayer object to the map as a new layer.
*/
useEffect(() => {
if (!map) {
return undefined;
}

MapUtils.addGeoreferenceLayer(map, props.id, {
manifest: props.manifest,
opacity: props.opacity,
url: props.url
});

return () => MapUtils.removeLayer(map, props.id);
}, [map]);

return null;
};

WarpedImageLayer.defaultProps = {
opacity: 0.5
};

export default WarpedImageLayer;
1 change: 1 addition & 0 deletions packages/geospatial/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { default as MapControl } from './components/MapControl';
export { default as MapDraw } from './components/MapDraw';
export { default as RasterLayer } from './components/RasterLayer';
export { default as WarpedImageLayer } from './components/WarpedImageLayer';
export { default as WarpedImageLayerPeripleo } from './components/WarpedImageLayerPeripleo';

// Utils
export { default as Map } from './utils/Map';
Expand Down
35 changes: 35 additions & 0 deletions packages/geospatial/src/utils/Map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// @flow

import { WarpedMapLayer } from '@allmaps/maplibre';
import { bbox, bboxPolygon, buffer } from '@turf/turf';
import _ from 'underscore';

Expand All @@ -8,6 +9,28 @@ const MAX_LATITUDE = 90;
const MIN_LONGITUDE = -180;
const MAX_LONGITUDE = 180;

/**
* Adds the geo-referenced image layer to the passed map.
*
* @param map
* @param layerId
* @param options
*/
const addGeoreferenceLayer = (map, layerId, options = {}) => {
const warpedMapLayer = new WarpedMapLayer(layerId);
map.addLayer(warpedMapLayer);

if (options.url) {
warpedMapLayer.addGeoreferenceAnnotationByUrl(options.url);
} else if (options.manifest) {
warpedMapLayer.addGeoreferenceAnnotation(options.manifest);
}

if (options.opacity) {
warpedMapLayer.setOpacity(options.opacity);
}
};

/**
* Returns a bounding box for the passed geometry (with optional buffer).
*
Expand Down Expand Up @@ -40,6 +63,16 @@ const getBoundingBox = (data, bufferDistance = null) => {
return bbox(polygonBuffer);
};

/**
* Removes a layer from the passed map.
*
* @param map
* @param layerId
*
* @returns {*}
*/
const removeLayer = (map, layerId) => map && map.removeLayer(layerId);

/**
* Validates that the passed bounding box contains finite coordinates.
*
Expand Down Expand Up @@ -72,7 +105,9 @@ const validateCoordinates = (coordinates) => {
};

export default {
addGeoreferenceLayer,
getBoundingBox,
removeLayer,
validateBoundingBox,
validateCoordinates
};
50 changes: 23 additions & 27 deletions packages/storybook/src/geospatial/WarpedImageLayer.stories.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// @flow

import { Map, Zoom } from '@peripleo/maplibre';
import { Controls, Peripleo } from '@peripleo/peripleo';
import maplibregl from 'maplibre-gl';
import React from 'react';
import WarpedImageLayer from '../../../geospatial/src/components/WarpedImageLayer';
import { Map } from 'react-map-gl';
import Env from '../utils/Environment';
import WarpedImageLayer from '../../../geospatial/src/components/WarpedImageLayer';

export default {
title: 'Components/Geospatial/WarpedImageLayer',
Expand All @@ -15,30 +15,26 @@ const mapTilerKey = Env.getMapTilerKey();
const mapStyle = `https://api.maptiler.com/maps/basic-v2/style.json?key=${mapTilerKey}`;

export const Default = () => (
<Peripleo>
<Map
defaultBounds={[
<Map
attributionControl={false}
initialViewState={{
bounds: [
[-74.123501, 40.679546],
[-73.796486, 40.805444]
]}
style={mapStyle}
>
<Controls
position='topright'
>
<Zoom />
</Controls>
<div
style={{
width: '100%',
height: '500px'
}}
>
<WarpedImageLayer
id='nyc'
url='https://annotations.allmaps.org/images/d180902cb93d5bf2'
/>
</div>
</Map>
</Peripleo>
]
}}
mapLib={maplibregl}
mapStyle={mapStyle}
maxPitch={0}
preserveDrawingBuffer
style={{
height: 500,
width: '100%'
}}
>
<WarpedImageLayer
id='nyc'
url='https://annotations.allmaps.org/images/d180902cb93d5bf2'
/>
</Map>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// @flow

import { Map as PeripleoMap, Zoom } from '@peripleo/maplibre';
import { Controls, Peripleo } from '@peripleo/peripleo';
import React from 'react';
import Env from '../utils/Environment';
import WarpedImageLayerPeripleo from '../../../geospatial/src/components/WarpedImageLayerPeripleo';

export default {
title: 'Components/Geospatial/WarpedImageLayerPeripleo',
component: WarpedImageLayerPeripleo
};

const mapTilerKey = Env.getMapTilerKey();
const mapStyle = `https://api.maptiler.com/maps/basic-v2/style.json?key=${mapTilerKey}`;

export const Default = () => (
<Peripleo>
<PeripleoMap
defaultBounds={[
[-74.123501, 40.679546],
[-73.796486, 40.805444]
]}
style={mapStyle}
>
<Controls
position='topright'
>
<Zoom />
</Controls>
<div
style={{
width: '100%',
height: '500px'
}}
>
<WarpedImageLayerPeripleo
id='nyc'
url='https://annotations.allmaps.org/images/d180902cb93d5bf2'
/>
</div>
</PeripleoMap>
</Peripleo>
);
4 changes: 2 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11321,7 +11321,7 @@ maplibre-gl@^3.6.2:
tinyqueue "^2.0.3"
vt-pbf "^3.1.3"

maplibre-gl@^4.0.0:
maplibre-gl@^4.0.0, maplibre-gl@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/maplibre-gl/-/maplibre-gl-4.5.0.tgz#aa5e6e214cb0cd35bc9a9f3c7417cb2092d96c58"
integrity sha512-qOS1hn4d/pn2i0uva4S5Oz+fACzTkgBKq+NpwT/Tqzi4MSyzcWNtDELzLUSgWqHfNIkGCl5CZ/w7dtis+t4RCw==
Expand Down Expand Up @@ -12977,7 +12977,7 @@ react-lifecycles-compat@^3.0.4:
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==

react-map-gl@^7.1.6:
react-map-gl@^7.1.6, react-map-gl@^7.1.7:
version "7.1.7"
resolved "https://registry.yarnpkg.com/react-map-gl/-/react-map-gl-7.1.7.tgz#f9b7d76cccad6d0bf1627d1827a0a378696ac1d0"
integrity sha512-mwjc0obkBJOXCcoXQr3VoLqmqwo9vS4bXfbGsdxXzEgVCv/PM0v+1QggL7W0d/ccIy+VCjbXNlGij+PENz6VNg==
Expand Down

0 comments on commit 4dd6f0f

Please sign in to comment.