From 8260b99bc8286d8ebed33dbf5e845811919aafcc Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Thu, 27 Apr 2023 10:54:27 +0200 Subject: [PATCH 1/6] Removed dead code --- packages/react-core/src/filters/tileFeaturesGeometries.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/react-core/src/filters/tileFeaturesGeometries.js b/packages/react-core/src/filters/tileFeaturesGeometries.js index 3195c23d4..306aa888e 100644 --- a/packages/react-core/src/filters/tileFeaturesGeometries.js +++ b/packages/react-core/src/filters/tileFeaturesGeometries.js @@ -166,10 +166,6 @@ function createIndicesForPoints(data) { data.pointIndices.value.set([lastFeatureId + 1], featureIds.length); } -export function getGeometryToIntersect(viewport, geometry) { - return geometry ? intersect(bboxPolygon(viewport), geometry) : bboxPolygon(viewport); -} - export default function tileFeaturesGeometries({ tiles, tileFormat, From ebdd99ca5baa8baad2273edf60ff4d8e7f0c7ea1 Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Thu, 27 Apr 2023 12:06:55 +0200 Subject: [PATCH 2/6] Changed behavior of getGeometryToIntersect --- .../__tests__/filters/tileFeatures.test.js | 114 +++++++++++++++--- .../react-core/src/filters/tileFeatures.d.ts | 4 +- .../react-core/src/filters/tileFeatures.js | 20 ++- 3 files changed, 115 insertions(+), 23 deletions(-) diff --git a/packages/react-core/__tests__/filters/tileFeatures.test.js b/packages/react-core/__tests__/filters/tileFeatures.test.js index c286032a5..93f7693f4 100644 --- a/packages/react-core/__tests__/filters/tileFeatures.test.js +++ b/packages/react-core/__tests__/filters/tileFeatures.test.js @@ -2,10 +2,68 @@ import { TILE_FORMATS } from '@deck.gl/carto'; import { geojsonToBinary } from '@loaders.gl/gis'; import { tileFeatures } from '../../src'; import * as transformToTileCoords from '../../src/utils/transformToTileCoords'; +import { getGeometryToIntersect } from '../../src/filters/tileFeatures'; + +/** @type { import('../../src').Viewport } */ +const viewport = [-10, -10, 10, 10]; // west - south - east - north + +const viewportFeature = { + bbox: viewport, + type: 'Feature', + properties: {}, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-10, -10], + [10, -10], + [10, 10], + [-10, 10], + [-10, -10] + ] + ] + } +}; + +/** @type { import('geojson').Feature } */ +const geometryFeature = { + type: 'Feature', + geometry: { + type: 'Polygon', + coordinates: [ + [ + [-1, -1], + [1, -1], + [1, 1], + [-1, 1], + [-1, -1] + ] + ] + }, + properties: {} +}; + +describe('getGeometryToIntersect', () => { + test('returns null in case no viewport or geometry is present', () => { + expect(getGeometryToIntersect(null, null)).toStrictEqual(null); + expect(getGeometryToIntersect([], null)).toStrictEqual(null); + }); + + test('returns the viewport as feature', () => { + expect(getGeometryToIntersect(viewport, null)).toStrictEqual(viewportFeature); + }); + + test('returns the geometry as feature', () => { + expect(getGeometryToIntersect(null, geometryFeature)).toStrictEqual(geometryFeature); + expect(getGeometryToIntersect(viewport, geometryFeature)).toStrictEqual( + geometryFeature + ); + }); +}); describe('viewport features with binary mode', () => { - const viewport = [-10, -10, 10, 10]; // west - south - east - north const [west, south, east, north] = viewport; + const tileFormat = TILE_FORMATS.BINARY; describe('return no data', () => { test('tiles are not visible', () => { @@ -13,7 +71,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport + viewport, + tileFormat }); expect(properties).toEqual([]); }); @@ -23,7 +82,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport + viewport, + tileFormat }); expect(properties).toEqual([]); }); @@ -33,7 +93,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport + viewport, + tileFormat }); expect(properties).toEqual([]); }); @@ -43,7 +104,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport + viewport, + tileFormat }); expect(properties).toEqual([]); }); @@ -75,7 +137,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); // prettier-ignore @@ -111,7 +174,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -146,7 +210,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -184,7 +249,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -220,7 +286,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); expect(properties).toEqual([{ cartodb_id: 1, other_prop: 1 }]); }); @@ -250,7 +317,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); expect(properties).toEqual([{ cartodb_id: 1, other_prop: 1 }]); }); @@ -280,7 +348,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); expect(properties).toEqual([{ cartodb_id: 1, other_prop: 1 }]); }); @@ -310,7 +379,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); expect(properties).toEqual([{ cartodb_id: 1, other_prop: 1 }]); }); @@ -343,7 +413,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'cartodb_id' + uniqueIdProperty: 'cartodb_id', + tileFormat }); expect(properties).toEqual([{ cartodb_id: 1, other_prop: 1 }]); }); @@ -389,7 +460,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, viewport, - uniqueIdProperty: undefined + uniqueIdProperty: undefined, + tileFormat }); // prettier-ignore @@ -426,7 +498,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: undefined + uniqueIdProperty: undefined, + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -462,7 +535,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: undefined + uniqueIdProperty: undefined, + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -497,7 +571,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: undefined + uniqueIdProperty: undefined, + tileFormat }); // prettier-ignore expect(properties).toEqual([ @@ -534,7 +609,8 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, viewport, - uniqueIdProperty: 'user_id' + uniqueIdProperty: 'user_id', + tileFormat }); // prettier-ignore expect(properties).toEqual([ diff --git a/packages/react-core/src/filters/tileFeatures.d.ts b/packages/react-core/src/filters/tileFeatures.d.ts index b30085f20..e668405e9 100644 --- a/packages/react-core/src/filters/tileFeatures.d.ts +++ b/packages/react-core/src/filters/tileFeatures.d.ts @@ -1,5 +1,5 @@ import { TileFeatures, TileFeaturesResponse } from '../types'; -import { Geometry, Feature, Polygon, MultiPolygon } from 'geojson'; +import { Feature, Polygon, MultiPolygon } from 'geojson'; -export function getGeometryToIntersect(viewport: number[], geometry: Geometry | null): Feature | null; +export function getGeometryToIntersect(viewport: number[] | null, geometry: Feature | null): Feature | null; export function tileFeatures(arg: TileFeatures): TileFeaturesResponse; \ No newline at end of file diff --git a/packages/react-core/src/filters/tileFeatures.js b/packages/react-core/src/filters/tileFeatures.js index fd352c21a..0321d331d 100644 --- a/packages/react-core/src/filters/tileFeatures.js +++ b/packages/react-core/src/filters/tileFeatures.js @@ -1,10 +1,26 @@ import bboxPolygon from '@turf/bbox-polygon'; -import intersect from '@turf/intersect'; import tileFeaturesGeometries from './tileFeaturesGeometries'; import tileFeaturesSpatialIndex from './tileFeaturesSpatialIndex'; +/** + * Select the geometry to use for widget calculation and data filtering. + * If a geometry (mask) is set, use the mask otherwise use the current viewport. + * Since it's possible that no mask and no viewport is set, return null in this case. + * + * @typedef { import('geojson').Polygon | import('geojson').MultiPolygon } Geometry + * @typedef { import('geojson').Feature } Feature + * @typedef { import('geojson').BBox } BBox + * + * @param { BBox? } viewport viewport [minX, minY, maxX, maxY], if any + * @param { Feature? } geometry the active mask, if any + * @returns { Feature? } the geometry to use for filtering + */ export function getGeometryToIntersect(viewport, geometry) { - return geometry ? intersect(bboxPolygon(viewport), geometry) : bboxPolygon(viewport); + return geometry + ? geometry + : Array.isArray(viewport) && viewport.length === 4 + ? bboxPolygon(viewport) + : null; } export function tileFeatures({ From 61777e8572bfa84cacfd5bf75dea2c70db3caa4f Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Thu, 27 Apr 2023 16:36:31 +0200 Subject: [PATCH 3/6] Refactor: reduced unneeded widget calculation --- .../react-api/src/hooks/useCartoLayerProps.js | 8 +-- .../react-api/src/hooks/useGeojsonFeatures.js | 14 ++--- .../react-api/src/hooks/useTileFeatures.js | 14 ++--- .../__tests__/filters/geojsonFeatures.test.js | 23 ++++--- .../__tests__/filters/tileFeatures.test.js | 62 +++++++------------ .../src/filters/geojsonFeatures.d.ts | 7 +-- .../react-core/src/filters/geojsonFeatures.js | 4 +- .../react-core/src/filters/tileFeatures.js | 5 +- packages/react-core/src/index.d.ts | 2 +- packages/react-core/src/index.js | 2 +- packages/react-core/src/types.d.ts | 5 +- .../react-redux/src/slices/cartoSlice.d.ts | 3 +- .../react-workers/__tests__/methods.test.js | 7 ++- packages/react-workers/src/workers/methods.js | 11 ++-- 14 files changed, 69 insertions(+), 98 deletions(-) diff --git a/packages/react-api/src/hooks/useCartoLayerProps.js b/packages/react-api/src/hooks/useCartoLayerProps.js index f78f73739..7d753f03f 100644 --- a/packages/react-api/src/hooks/useCartoLayerProps.js +++ b/packages/react-api/src/hooks/useCartoLayerProps.js @@ -7,6 +7,7 @@ import { getDataFilterExtensionProps } from './dataFilterExtensionUtil'; import { getMaskExtensionProps } from './maskExtensionUtil'; import FeaturesDroppedLoader from './FeaturesDroppedLoader'; import { CLIENT_ID } from '../api/common'; +import { getGeometryToIntersect } from '@carto/react-core'; const LOADERS = [FeaturesDroppedLoader]; @@ -19,19 +20,18 @@ export default function useCartoLayerProps({ }) { const viewport = useSelector((state) => state.carto.viewport); const spatialFilter = useSelector((state) => selectSpatialFilter(state, source?.id)); + const geometryToIntersect = getGeometryToIntersect(viewport, spatialFilter); const [onDataLoadForGeojson] = useGeojsonFeatures({ source, - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, debounceTimeout: viewporFeaturesDebounceTimeout }); const [onDataLoadForTile, onViewportLoad, fetch] = useTileFeatures({ source, - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, debounceTimeout: viewporFeaturesDebounceTimeout }); diff --git a/packages/react-api/src/hooks/useGeojsonFeatures.js b/packages/react-api/src/hooks/useGeojsonFeatures.js index cd2a1d15b..263336275 100644 --- a/packages/react-api/src/hooks/useGeojsonFeatures.js +++ b/packages/react-api/src/hooks/useGeojsonFeatures.js @@ -6,8 +6,7 @@ import useFeaturesCommons from './useFeaturesCommons'; export default function useGeojsonFeatures({ source, - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, debounceTimeout = 250 }) { @@ -23,10 +22,9 @@ export default function useGeojsonFeatures({ const sourceId = source?.id; const computeFeatures = useCallback( - ({ viewport, spatialFilter, uniqueIdProperty }) => { + ({ geometryToIntersect, uniqueIdProperty }) => { executeTask(sourceId, Methods.GEOJSON_FEATURES, { - viewport, - geometry: spatialFilter, + geometryToIntersect, uniqueIdProperty }) .then(() => { @@ -48,14 +46,12 @@ export default function useGeojsonFeatures({ clearDebounce(); setSourceFeaturesReady(false); debounceIdRef.current = debouncedComputeFeatures({ - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty }); } }, [ - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, sourceId, isGeoJsonLoaded, diff --git a/packages/react-api/src/hooks/useTileFeatures.js b/packages/react-api/src/hooks/useTileFeatures.js index 501594ff6..6e85e6f2f 100644 --- a/packages/react-api/src/hooks/useTileFeatures.js +++ b/packages/react-api/src/hooks/useTileFeatures.js @@ -10,8 +10,7 @@ import { useDispatch } from 'react-redux'; export default function useTileFeatures({ source, - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, debounceTimeout = 250 }) { @@ -32,7 +31,7 @@ export default function useTileFeatures({ const sourceId = source?.id; const computeFeatures = useCallback( - ({ viewport, spatialFilter, uniqueIdProperty }) => { + ({ geometryToIntersect, uniqueIdProperty }) => { if (!tileFormat) { return null; } @@ -40,8 +39,7 @@ export default function useTileFeatures({ setSourceFeaturesReady(false); executeTask(sourceId, Methods.TILE_FEATURES, { - viewport, - geometry: spatialFilter, + geometryToIntersect, uniqueIdProperty, tileFormat, geoColumName, @@ -101,14 +99,12 @@ export default function useTileFeatures({ clearDebounce(); setSourceFeaturesReady(false); debounceIdRef.current = debouncedComputeFeatures({ - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty }); } }, [ - viewport, - spatialFilter, + geometryToIntersect, uniqueIdProperty, debouncedComputeFeatures, sourceId, diff --git a/packages/react-core/__tests__/filters/geojsonFeatures.test.js b/packages/react-core/__tests__/filters/geojsonFeatures.test.js index 5742ebe83..05806ca1b 100644 --- a/packages/react-core/__tests__/filters/geojsonFeatures.test.js +++ b/packages/react-core/__tests__/filters/geojsonFeatures.test.js @@ -1,7 +1,10 @@ +import bboxPolygon from '@turf/bbox-polygon'; import { geojsonFeatures } from '../../src/filters/geojsonFeatures'; describe('viewport features with geojson data', () => { + /** @type { import('../../src').Viewport } */ const viewport = [-10, -10, 10, 10]; // west - south - east - north + const viewportFeature = bboxPolygon(viewport); describe('return no data', () => { test('should return an empty array if no geojson features present', () => { @@ -12,7 +15,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson, - viewport + geometryToIntersect: viewportFeature }); expect(properties).toEqual([]); @@ -39,7 +42,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: linestrings, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -70,7 +73,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multilinestrings, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -101,7 +104,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: polygons, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -135,7 +138,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multipolygons, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -167,7 +170,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: points, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -193,7 +196,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: linestrings, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -219,7 +222,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multilinestrings, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -245,7 +248,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: polygons, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); @@ -274,7 +277,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multipolygons, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id' }); diff --git a/packages/react-core/__tests__/filters/tileFeatures.test.js b/packages/react-core/__tests__/filters/tileFeatures.test.js index 93f7693f4..c82f06230 100644 --- a/packages/react-core/__tests__/filters/tileFeatures.test.js +++ b/packages/react-core/__tests__/filters/tileFeatures.test.js @@ -3,27 +3,11 @@ import { geojsonToBinary } from '@loaders.gl/gis'; import { tileFeatures } from '../../src'; import * as transformToTileCoords from '../../src/utils/transformToTileCoords'; import { getGeometryToIntersect } from '../../src/filters/tileFeatures'; +import bboxPolygon from '@turf/bbox-polygon'; /** @type { import('../../src').Viewport } */ const viewport = [-10, -10, 10, 10]; // west - south - east - north - -const viewportFeature = { - bbox: viewport, - type: 'Feature', - properties: {}, - geometry: { - type: 'Polygon', - coordinates: [ - [ - [-10, -10], - [10, -10], - [10, 10], - [-10, 10], - [-10, -10] - ] - ] - } -}; +const viewportFeature = bboxPolygon(viewport); /** @type { import('geojson').Feature } */ const geometryFeature = { @@ -71,7 +55,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport, + geometryToIntersect: viewportFeature, tileFormat }); expect(properties).toEqual([]); @@ -82,7 +66,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport, + geometryToIntersect: viewportFeature, tileFormat }); expect(properties).toEqual([]); @@ -93,7 +77,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport, + geometryToIntersect: viewportFeature, tileFormat }); expect(properties).toEqual([]); @@ -104,7 +88,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport, + geometryToIntersect: viewportFeature, tileFormat }); expect(properties).toEqual([]); @@ -136,7 +120,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -173,7 +157,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -209,7 +193,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -248,7 +232,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -285,7 +269,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -316,7 +300,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -347,7 +331,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -378,7 +362,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -412,7 +396,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -459,7 +443,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: undefined, tileFormat }); @@ -497,7 +481,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: undefined, tileFormat }); @@ -534,7 +518,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: undefined, tileFormat }); @@ -570,7 +554,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: undefined, tileFormat }); @@ -608,7 +592,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, uniqueIdProperty: 'user_id', tileFormat }); @@ -643,21 +627,21 @@ describe('viewport features with binary mode', () => { tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, tileFormat: TILE_FORMATS.GEOJSON }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(0); tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, tileFormat: TILE_FORMATS.BINARY }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(0); tileFeatures({ tiles: mockedTile, - viewport, + geometryToIntersect: viewportFeature, tileFormat: TILE_FORMATS.MVT }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(1); diff --git a/packages/react-core/src/filters/geojsonFeatures.d.ts b/packages/react-core/src/filters/geojsonFeatures.d.ts index dc300618e..018641cbb 100644 --- a/packages/react-core/src/filters/geojsonFeatures.d.ts +++ b/packages/react-core/src/filters/geojsonFeatures.d.ts @@ -1,10 +1,9 @@ -import { FeatureCollection, Geometry } from 'geojson'; -import { Viewport, TileFeaturesResponse } from '../types'; +import { FeatureCollection, Feature, Polygon, MultiPolygon } from 'geojson'; +import { TileFeaturesResponse } from '../types'; type GeojsonFeaturesArgs = { geojson: FeatureCollection, - viewport: Viewport, - geometry?: Geometry + geometryToIntersect: Feature | null, uniqueIdProperty?: string } diff --git a/packages/react-core/src/filters/geojsonFeatures.js b/packages/react-core/src/filters/geojsonFeatures.js index 5c7693ddc..355a7e0f9 100644 --- a/packages/react-core/src/filters/geojsonFeatures.js +++ b/packages/react-core/src/filters/geojsonFeatures.js @@ -1,11 +1,9 @@ import intersects from '@turf/boolean-intersects'; -import { getGeometryToIntersect } from './tileFeatures'; -export function geojsonFeatures({ geojson, viewport, geometry, uniqueIdProperty }) { +export function geojsonFeatures({ geojson, geometryToIntersect, uniqueIdProperty }) { let uniqueIdx = 0; // Map is used to cache multi geometries. Only a sucessfull intersect by multipolygon const map = new Map(); - const geometryToIntersect = getGeometryToIntersect(viewport, geometry); if (!geometryToIntersect) { return []; diff --git a/packages/react-core/src/filters/tileFeatures.js b/packages/react-core/src/filters/tileFeatures.js index 0321d331d..295b732d3 100644 --- a/packages/react-core/src/filters/tileFeatures.js +++ b/packages/react-core/src/filters/tileFeatures.js @@ -25,15 +25,12 @@ export function getGeometryToIntersect(viewport, geometry) { export function tileFeatures({ tiles, - viewport, - geometry, + geometryToIntersect, uniqueIdProperty, tileFormat, geoColumName, spatialIndex }) { - const geometryToIntersect = getGeometryToIntersect(viewport, geometry); - if (!geometryToIntersect) { return []; } diff --git a/packages/react-core/src/index.d.ts b/packages/react-core/src/index.d.ts index d0e0c8cb9..b89218369 100644 --- a/packages/react-core/src/index.d.ts +++ b/packages/react-core/src/index.d.ts @@ -25,7 +25,7 @@ export { scatterPlot } from './operations/scatterPlot'; export { FilterTypes as _FilterTypes } from './filters/FilterTypes'; -export { tileFeatures } from './filters/tileFeatures'; +export { tileFeatures, getGeometryToIntersect } from './filters/tileFeatures'; export { geojsonFeatures } from './filters/geojsonFeatures'; export { AggregationFunctions, GroupByFeature, HistogramFeature, Viewport, TileFeatures } from './types'; diff --git a/packages/react-core/src/index.js b/packages/react-core/src/index.js index 634e7becb..d55052d3a 100644 --- a/packages/react-core/src/index.js +++ b/packages/react-core/src/index.js @@ -34,7 +34,7 @@ export { applyFilters as _applyFilters } from './filters/Filter'; -export { tileFeatures } from './filters/tileFeatures'; +export { tileFeatures, getGeometryToIntersect } from './filters/tileFeatures'; export { geojsonFeatures } from './filters/geojsonFeatures'; export { GroupDateTypes } from './operations/constants/GroupDateTypes'; diff --git a/packages/react-core/src/types.d.ts b/packages/react-core/src/types.d.ts index 29220e9d2..37d61bc6e 100644 --- a/packages/react-core/src/types.d.ts +++ b/packages/react-core/src/types.d.ts @@ -1,6 +1,6 @@ import { TILE_FORMATS } from '@deck.gl/carto'; import { AggregationTypes } from './operations/constants/AggregationTypes'; -import { Geometry } from 'geojson'; +import { Feature, Polygon, MultiPolygon } from 'geojson'; import { SpatialIndex } from './operations/constants/SpatialIndexTypes'; export type AggregationFunctions = Record< @@ -27,8 +27,7 @@ export type Viewport = [number, number, number, number]; export type TileFeatures = { tiles?: any; // TODO: add proper deck.gl type - viewport: Viewport; - geometry?: Geometry; + geometryToIntersect: Feature | null; uniqueIdProperty?: string; tileFormat: TILE_FORMATS; geoColumName?: string; diff --git a/packages/react-redux/src/slices/cartoSlice.d.ts b/packages/react-redux/src/slices/cartoSlice.d.ts index 7b5103745..68c95f0e0 100644 --- a/packages/react-redux/src/slices/cartoSlice.d.ts +++ b/packages/react-redux/src/slices/cartoSlice.d.ts @@ -4,6 +4,7 @@ import { FiltersLogicalOperators, _FilterTypes } from '@carto/react-core'; import { CartoBasemapsNames, GMapsBasemapsNames } from '@carto/react-basemaps/'; import { InitialCartoState, CartoState, ViewState } from '../types'; import { AnyAction, Reducer } from 'redux'; +import { Feature, Polygon, MultiPolygon } from 'geojson'; type Source = SourceProps & { id: string @@ -158,6 +159,6 @@ export function setFeatureSelectionEnabled(enabled: boolean): { payload: boolean; }; -export function selectSpatialFilter(state: any, sourceId?: string): object | null; +export function selectSpatialFilter(state: any, sourceId?: string): Feature | null; export function selectFeatureSelectionMode(state: any): string | null; diff --git a/packages/react-workers/__tests__/methods.test.js b/packages/react-workers/__tests__/methods.test.js index 6350a2247..93b6eecc3 100644 --- a/packages/react-workers/__tests__/methods.test.js +++ b/packages/react-workers/__tests__/methods.test.js @@ -1,3 +1,4 @@ +import bboxPolygon from '@turf/bbox-polygon'; import { getFormula, getHistogram, @@ -11,10 +12,10 @@ describe('Worker Methods', () => { beforeEach(() => { loadGeoJSONFeatures({ geojson: sampleGeoJson }); getGeojsonFeatures({ - viewport: [ + geometryToIntersect: bboxPolygon([ -119.8541879250893, 19.66738891368218, -61.31673251486329, 54.38309840045979 - ], - geometry: null + ]), + uniqueIdProperty: undefined }); }); describe('getFormula', () => { diff --git a/packages/react-workers/src/workers/methods.js b/packages/react-workers/src/workers/methods.js index 7a3bdd64d..03d44f0a2 100644 --- a/packages/react-workers/src/workers/methods.js +++ b/packages/react-workers/src/workers/methods.js @@ -17,8 +17,7 @@ let currentGeoJSON; let currentTiles; export function getTileFeatures({ - viewport, - geometry, + geometryToIntersect, uniqueIdProperty, tileFormat, geoColumName, @@ -26,8 +25,7 @@ export function getTileFeatures({ }) { currentFeatures = tileFeatures({ tiles: currentTiles, - viewport, - geometry, + geometryToIntersect, uniqueIdProperty, tileFormat, geoColumName, @@ -46,12 +44,11 @@ export function loadGeoJSONFeatures({ geojson }) { return true; } -export function getGeojsonFeatures({ viewport, geometry, uniqueIdProperty }) { +export function getGeojsonFeatures({ geometryToIntersect, uniqueIdProperty }) { if (currentGeoJSON) { currentFeatures = geojsonFeatures({ geojson: currentGeoJSON, - viewport, - geometry, + geometryToIntersect, uniqueIdProperty }); } From bb7cc408ae0b62bd8ea7611fc12417ab92728b49 Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Fri, 28 Apr 2023 11:00:51 +0200 Subject: [PATCH 4/6] Refactor: getGeometryToIntersect returns a Geometry --- .../react-api/src/hooks/useGeojsonFeatures.js | 3 +- .../__tests__/filters/geojsonFeatures.test.js | 32 ++++--- .../__tests__/filters/tileFeatures.test.js | 86 +++++++++---------- .../src/filters/geojsonFeatures.d.ts | 4 +- .../react-core/src/filters/tileFeatures.d.ts | 2 +- .../react-core/src/filters/tileFeatures.js | 14 +-- .../src/filters/tileFeaturesGeometries.d.ts | 4 +- .../src/filters/tileFeaturesSpatialIndex.d.ts | 4 +- .../src/filters/tileFeaturesSpatialIndex.js | 6 +- packages/react-core/src/types.d.ts | 4 +- .../react-workers/__tests__/methods.test.js | 2 +- 11 files changed, 84 insertions(+), 77 deletions(-) diff --git a/packages/react-api/src/hooks/useGeojsonFeatures.js b/packages/react-api/src/hooks/useGeojsonFeatures.js index 263336275..e1f2e6abf 100644 --- a/packages/react-api/src/hooks/useGeojsonFeatures.js +++ b/packages/react-api/src/hooks/useGeojsonFeatures.js @@ -25,7 +25,8 @@ export default function useGeojsonFeatures({ ({ geometryToIntersect, uniqueIdProperty }) => { executeTask(sourceId, Methods.GEOJSON_FEATURES, { geometryToIntersect, - uniqueIdProperty + uniqueIdProperty, + tileFormat: undefined }) .then(() => { setSourceFeaturesReady(true); diff --git a/packages/react-core/__tests__/filters/geojsonFeatures.test.js b/packages/react-core/__tests__/filters/geojsonFeatures.test.js index 05806ca1b..361062a10 100644 --- a/packages/react-core/__tests__/filters/geojsonFeatures.test.js +++ b/packages/react-core/__tests__/filters/geojsonFeatures.test.js @@ -4,10 +4,11 @@ import { geojsonFeatures } from '../../src/filters/geojsonFeatures'; describe('viewport features with geojson data', () => { /** @type { import('../../src').Viewport } */ const viewport = [-10, -10, 10, 10]; // west - south - east - north - const viewportFeature = bboxPolygon(viewport); + const viewportGeometry = bboxPolygon(viewport).geometry; describe('return no data', () => { test('should return an empty array if no geojson features present', () => { + /** @type { import('geojson').FeatureCollection } */ const geojson = { type: 'FeatureCollection', features: [] @@ -15,7 +16,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson, - geometryToIntersect: viewportFeature + geometryToIntersect: viewportGeometry }); expect(properties).toEqual([]); @@ -24,6 +25,7 @@ describe('viewport features with geojson data', () => { describe('correctly returns data', () => { test('should handle linestrings correctly fwsf', () => { + /** @type { import('geojson').FeatureCollection } */ const linestrings = { type: 'FeatureCollection', features: [...Array(3)].map((_, i) => ({ @@ -42,7 +44,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: linestrings, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -55,6 +57,7 @@ describe('viewport features with geojson data', () => { }); test('should handle multilinestrings correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const multilinestrings = { type: 'FeatureCollection', features: [...Array(3)].map((_, i) => ({ @@ -73,7 +76,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multilinestrings, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -86,6 +89,7 @@ describe('viewport features with geojson data', () => { }); test('should handle polygons correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const polygons = { type: 'FeatureCollection', features: [...Array(3)].map((_, i) => ({ @@ -104,7 +108,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: polygons, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -117,6 +121,7 @@ describe('viewport features with geojson data', () => { }); test('should handle multilipolygons correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const multipolygons = { type: 'FeatureCollection', features: [...Array(3)].map((_, i) => ({ @@ -138,7 +143,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multipolygons, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -153,6 +158,7 @@ describe('viewport features with geojson data', () => { describe('with repeated features', () => { test('should handle points correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const points = { type: 'FeatureCollection', features: [...Array(4)].map(() => ({ @@ -170,7 +176,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: points, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -178,6 +184,7 @@ describe('viewport features with geojson data', () => { }); test('should handle linestrings correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const linestrings = { type: 'FeatureCollection', features: [...Array(4)].map(() => ({ @@ -196,7 +203,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: linestrings, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -204,6 +211,7 @@ describe('viewport features with geojson data', () => { }); test('should handle multilinestrings correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const multilinestrings = { type: 'FeatureCollection', features: [...Array(4)].map(() => ({ @@ -222,7 +230,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multilinestrings, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -230,6 +238,7 @@ describe('viewport features with geojson data', () => { }); test('should handle polygons correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const polygons = { type: 'FeatureCollection', features: [...Array(4)].map(() => ({ @@ -248,7 +257,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: polygons, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); @@ -256,6 +265,7 @@ describe('viewport features with geojson data', () => { }); test('should handle multipolygons correctly', () => { + /** @type { import('geojson').FeatureCollection } */ const multipolygons = { type: 'FeatureCollection', features: [...Array(4)].map(() => ({ @@ -277,7 +287,7 @@ describe('viewport features with geojson data', () => { const properties = geojsonFeatures({ geojson: multipolygons, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id' }); diff --git a/packages/react-core/__tests__/filters/tileFeatures.test.js b/packages/react-core/__tests__/filters/tileFeatures.test.js index c82f06230..d2cf4f954 100644 --- a/packages/react-core/__tests__/filters/tileFeatures.test.js +++ b/packages/react-core/__tests__/filters/tileFeatures.test.js @@ -7,23 +7,25 @@ import bboxPolygon from '@turf/bbox-polygon'; /** @type { import('../../src').Viewport } */ const viewport = [-10, -10, 10, 10]; // west - south - east - north -const viewportFeature = bboxPolygon(viewport); - +const viewportGeometry = bboxPolygon(viewport).geometry; + +/** @type { import('geojson').Polygon } */ +const filterGeometry = { + type: 'Polygon', + coordinates: [ + [ + [-1, -1], + [1, -1], + [1, 1], + [-1, 1], + [-1, -1] + ] + ] +}; /** @type { import('geojson').Feature } */ -const geometryFeature = { +const filterFeature = { type: 'Feature', - geometry: { - type: 'Polygon', - coordinates: [ - [ - [-1, -1], - [1, -1], - [1, 1], - [-1, 1], - [-1, -1] - ] - ] - }, + geometry: filterGeometry, properties: {} }; @@ -33,15 +35,13 @@ describe('getGeometryToIntersect', () => { expect(getGeometryToIntersect([], null)).toStrictEqual(null); }); - test('returns the viewport as feature', () => { - expect(getGeometryToIntersect(viewport, null)).toStrictEqual(viewportFeature); + test('returns the viewport as geometry', () => { + expect(getGeometryToIntersect(viewport, null)).toStrictEqual(viewportGeometry); }); - test('returns the geometry as feature', () => { - expect(getGeometryToIntersect(null, geometryFeature)).toStrictEqual(geometryFeature); - expect(getGeometryToIntersect(viewport, geometryFeature)).toStrictEqual( - geometryFeature - ); + test('returns the filter as geometry', () => { + expect(getGeometryToIntersect(null, filterFeature)).toStrictEqual(filterGeometry); + expect(getGeometryToIntersect(viewport, filterFeature)).toStrictEqual(filterGeometry); }); }); @@ -55,7 +55,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat }); expect(properties).toEqual([]); @@ -66,7 +66,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat }); expect(properties).toEqual([]); @@ -77,7 +77,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat }); expect(properties).toEqual([]); @@ -88,7 +88,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat }); expect(properties).toEqual([]); @@ -120,7 +120,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -157,7 +157,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -193,7 +193,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -232,7 +232,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -269,7 +269,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -300,7 +300,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -331,7 +331,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -362,7 +362,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -396,7 +396,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'cartodb_id', tileFormat }); @@ -443,7 +443,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTiles, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: undefined, tileFormat }); @@ -481,7 +481,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: undefined, tileFormat }); @@ -518,7 +518,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: undefined, tileFormat }); @@ -554,7 +554,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: undefined, tileFormat }); @@ -592,7 +592,7 @@ describe('viewport features with binary mode', () => { const properties = tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, uniqueIdProperty: 'user_id', tileFormat }); @@ -627,21 +627,21 @@ describe('viewport features with binary mode', () => { tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat: TILE_FORMATS.GEOJSON }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(0); tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat: TILE_FORMATS.BINARY }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(0); tileFeatures({ tiles: mockedTile, - geometryToIntersect: viewportFeature, + geometryToIntersect: viewportGeometry, tileFormat: TILE_FORMATS.MVT }); expect(transformToTileCoordsSpy).toHaveBeenCalledTimes(1); diff --git a/packages/react-core/src/filters/geojsonFeatures.d.ts b/packages/react-core/src/filters/geojsonFeatures.d.ts index 018641cbb..3a55a2715 100644 --- a/packages/react-core/src/filters/geojsonFeatures.d.ts +++ b/packages/react-core/src/filters/geojsonFeatures.d.ts @@ -1,9 +1,9 @@ -import { FeatureCollection, Feature, Polygon, MultiPolygon } from 'geojson'; +import { FeatureCollection, Polygon, MultiPolygon } from 'geojson'; import { TileFeaturesResponse } from '../types'; type GeojsonFeaturesArgs = { geojson: FeatureCollection, - geometryToIntersect: Feature | null, + geometryToIntersect: Polygon | MultiPolygon | null, uniqueIdProperty?: string } diff --git a/packages/react-core/src/filters/tileFeatures.d.ts b/packages/react-core/src/filters/tileFeatures.d.ts index e668405e9..7a441deb6 100644 --- a/packages/react-core/src/filters/tileFeatures.d.ts +++ b/packages/react-core/src/filters/tileFeatures.d.ts @@ -1,5 +1,5 @@ import { TileFeatures, TileFeaturesResponse } from '../types'; import { Feature, Polygon, MultiPolygon } from 'geojson'; -export function getGeometryToIntersect(viewport: number[] | null, geometry: Feature | null): Feature | null; +export function getGeometryToIntersect(viewport: number[] | null, spatialFilter: Feature | null): Polygon | MultiPolygon | null; export function tileFeatures(arg: TileFeatures): TileFeaturesResponse; \ No newline at end of file diff --git a/packages/react-core/src/filters/tileFeatures.js b/packages/react-core/src/filters/tileFeatures.js index 295b732d3..0160b97db 100644 --- a/packages/react-core/src/filters/tileFeatures.js +++ b/packages/react-core/src/filters/tileFeatures.js @@ -4,7 +4,7 @@ import tileFeaturesSpatialIndex from './tileFeaturesSpatialIndex'; /** * Select the geometry to use for widget calculation and data filtering. - * If a geometry (mask) is set, use the mask otherwise use the current viewport. + * If a spatial filter (mask) is set, use the mask otherwise use the current viewport. * Since it's possible that no mask and no viewport is set, return null in this case. * * @typedef { import('geojson').Polygon | import('geojson').MultiPolygon } Geometry @@ -12,14 +12,14 @@ import tileFeaturesSpatialIndex from './tileFeaturesSpatialIndex'; * @typedef { import('geojson').BBox } BBox * * @param { BBox? } viewport viewport [minX, minY, maxX, maxY], if any - * @param { Feature? } geometry the active mask, if any - * @returns { Feature? } the geometry to use for filtering + * @param { Feature? } spatialFilter the active spatial filter (mask), if any + * @returns { Geometry? } the geometry to use for filtering */ -export function getGeometryToIntersect(viewport, geometry) { - return geometry - ? geometry +export function getGeometryToIntersect(viewport, spatialFilter) { + return spatialFilter + ? spatialFilter.geometry : Array.isArray(viewport) && viewport.length === 4 - ? bboxPolygon(viewport) + ? bboxPolygon(viewport).geometry : null; } diff --git a/packages/react-core/src/filters/tileFeaturesGeometries.d.ts b/packages/react-core/src/filters/tileFeaturesGeometries.d.ts index 9a8172dcb..d6f6daf47 100644 --- a/packages/react-core/src/filters/tileFeaturesGeometries.d.ts +++ b/packages/react-core/src/filters/tileFeaturesGeometries.d.ts @@ -1,11 +1,11 @@ import { TILE_FORMATS } from '@deck.gl/carto'; -import { Feature, Polygon, MultiPolygon } from 'geojson'; +import { Polygon, MultiPolygon } from 'geojson'; import { TileFeaturesResponse } from "../types"; export default function tileFeaturesGeometries(arg: { tiles: any; tileFormat: TILE_FORMATS; - geometryToIntersect: Feature; + geometryToIntersect: Polygon | MultiPolygon; uniqueIdProperty?: string; }): TileFeaturesResponse; diff --git a/packages/react-core/src/filters/tileFeaturesSpatialIndex.d.ts b/packages/react-core/src/filters/tileFeaturesSpatialIndex.d.ts index 140d9dbcd..bd46ea865 100644 --- a/packages/react-core/src/filters/tileFeaturesSpatialIndex.d.ts +++ b/packages/react-core/src/filters/tileFeaturesSpatialIndex.d.ts @@ -1,10 +1,10 @@ -import { Feature, Polygon, MultiPolygon } from 'geojson'; +import { Polygon, MultiPolygon } from 'geojson'; import { SpatialIndex } from "../operations/constants/SpatialIndexTypes"; import { TileFeaturesResponse } from "../types"; export default function tileFeaturesSpatialIndex(arg: { tiles: any; - geometryToIntersect: Feature; + geometryToIntersect: Polygon | MultiPolygon; geoColumName: string; spatialIndex: SpatialIndex; }): TileFeaturesResponse; diff --git a/packages/react-core/src/filters/tileFeaturesSpatialIndex.js b/packages/react-core/src/filters/tileFeaturesSpatialIndex.js index b9f2b2756..9913951f2 100644 --- a/packages/react-core/src/filters/tileFeaturesSpatialIndex.js +++ b/packages/react-core/src/filters/tileFeaturesSpatialIndex.js @@ -20,11 +20,7 @@ export default function tileFeaturesSpatialIndex({ if (!resolution) { return []; } - const cells = getCellsCoverGeometry( - geometryToIntersect.geometry, - spatialIndex, - resolution - ); + const cells = getCellsCoverGeometry(geometryToIntersect, spatialIndex, resolution); if (!cells?.length) { return []; diff --git a/packages/react-core/src/types.d.ts b/packages/react-core/src/types.d.ts index 37d61bc6e..c34edc746 100644 --- a/packages/react-core/src/types.d.ts +++ b/packages/react-core/src/types.d.ts @@ -1,6 +1,6 @@ import { TILE_FORMATS } from '@deck.gl/carto'; import { AggregationTypes } from './operations/constants/AggregationTypes'; -import { Feature, Polygon, MultiPolygon } from 'geojson'; +import { Polygon, MultiPolygon } from 'geojson'; import { SpatialIndex } from './operations/constants/SpatialIndexTypes'; export type AggregationFunctions = Record< @@ -27,7 +27,7 @@ export type Viewport = [number, number, number, number]; export type TileFeatures = { tiles?: any; // TODO: add proper deck.gl type - geometryToIntersect: Feature | null; + geometryToIntersect: Polygon | MultiPolygon | null; uniqueIdProperty?: string; tileFormat: TILE_FORMATS; geoColumName?: string; diff --git a/packages/react-workers/__tests__/methods.test.js b/packages/react-workers/__tests__/methods.test.js index 93b6eecc3..3f9c478e5 100644 --- a/packages/react-workers/__tests__/methods.test.js +++ b/packages/react-workers/__tests__/methods.test.js @@ -14,7 +14,7 @@ describe('Worker Methods', () => { getGeojsonFeatures({ geometryToIntersect: bboxPolygon([ -119.8541879250893, 19.66738891368218, -61.31673251486329, 54.38309840045979 - ]), + ]).geometry, uniqueIdProperty: undefined }); }); From 3389ceedd668d2dd497c10c35a9f41950c313638 Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Tue, 2 May 2023 17:04:02 +0200 Subject: [PATCH 5/6] Changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac235bee2..094bdda23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Not released +- Changed the way widget are calculated when a mask is set: use just the mask, no more intersection between mask and viewport [#661](https://github.com/CartoDB/carto-react/pull/661) - LegendCategories component migrated from makeStyles to styled-components + cleanup [#634](https://github.com/CartoDB/carto-react/pull/634) - LegendProportion component migrated from makeStyles to styled-components + cleanup [#635](https://github.com/CartoDB/carto-react/pull/635) - LegendRamp component migrated from makeStyles to styled-components + cleanup [#636](https://github.com/CartoDB/carto-react/pull/636) From fa29e3a822ce0d7d5e368479d01b0e8134b54842 Mon Sep 17 00:00:00 2001 From: Stefano Pettini Date: Wed, 3 May 2023 17:29:10 +0200 Subject: [PATCH 6/6] Minor --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 094bdda23..023dd2813 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Not released -- Changed the way widget are calculated when a mask is set: use just the mask, no more intersection between mask and viewport [#661](https://github.com/CartoDB/carto-react/pull/661) +- Changed how widget are calculated when a mask is set: use just the mask, no more intersection between mask and viewport [#661](https://github.com/CartoDB/carto-react/pull/661) - LegendCategories component migrated from makeStyles to styled-components + cleanup [#634](https://github.com/CartoDB/carto-react/pull/634) - LegendProportion component migrated from makeStyles to styled-components + cleanup [#635](https://github.com/CartoDB/carto-react/pull/635) - LegendRamp component migrated from makeStyles to styled-components + cleanup [#636](https://github.com/CartoDB/carto-react/pull/636)