Skip to content

Commit

Permalink
[fix] Improved map bounds calculation and handled latitude issues (#2632
Browse files Browse the repository at this point in the history
)

Signed-off-by: Ihor Dykhta <dikhta.igor@gmail.com>
  • Loading branch information
igorDykhta authored Sep 13, 2024
1 parent 7e3ea28 commit 16a3ac2
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
42 changes: 29 additions & 13 deletions src/reducers/src/data-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,34 @@ const MIN_LATITUDE = -90;
const MAX_LONGITUDE = 180;
const MIN_LONGITUDE = -180;

/**
* takes a list of layer bounds and returns a single bound
*/
export function processLayerBounds(layerBounds: Bounds[]): Bounds {
return layerBounds.reduce(
(res, b) => {
const minLongitude = Math.min(res[0], b[0]);
const minLatitude = Math.min(res[1], b[1]);
const maxLongitude = Math.max(res[2], b[2]);
const maxLatitude = Math.max(res[3], b[3]);

// for some reason WebMercatorViewport can't handle latitude -90,90 and throws an error
// so we default to lat/lng (0,0)
// viewport.js:81 Uncaught Error: Pixel project matrix not invertible
// at WebMercatorViewport16.Viewport5 (viewport.js:81:13)
// at new WebMercatorViewport16 (web-mercator-viewport.js:92:5)
// at getViewportFromMapState (map-utils.js:46:66)
return [
minLongitude <= MIN_LONGITUDE ? 0 : minLongitude,
minLatitude <= MIN_LATITUDE ? 0 : minLatitude,
maxLongitude >= MAX_LONGITUDE ? 0 : maxLongitude,
maxLatitude >= MAX_LATITUDE ? 0 : maxLatitude
];
},
[MAX_LONGITUDE, MAX_LATITUDE, MIN_LONGITUDE, MIN_LATITUDE]
);
}

/**
* return center of map from given points
* @param layers
Expand All @@ -29,17 +57,5 @@ export function findMapBounds(layers: Layer[]): Bounds | null {
return null;
}
// merge bounds in each layer
const newBounds = (availableLayerBounds as Bounds).reduce(
(res, b) => {
return [
Math.min(res[0], b[0]),
Math.min(res[1], b[1]),
Math.max(res[2], b[2]),
Math.max(res[3], b[3])
];
},
[MAX_LONGITUDE, MAX_LATITUDE, MIN_LONGITUDE, MIN_LATITUDE]
);
// @ts-expect-error
return newBounds;
return processLayerBounds(availableLayerBounds);
}
42 changes: 42 additions & 0 deletions test/node/utils/data-utils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
formatNumber,
roundToFour
} from '@kepler.gl/utils';
import {processLayerBounds} from '@kepler.gl/reducers';
import {ALL_FIELD_TYPES} from '@kepler.gl/constants';

test('dataUtils -> clamp', t => {
Expand Down Expand Up @@ -237,3 +238,44 @@ test('dataUtils -> formatNumber', t => {

t.end();
});

test('dataUtils -> validateBounds', t => {
const TEST_CASES = [
{
input: [[10, -10, 20, -20]],
output: [10, -10, 20, -20],
message: 'should return the same bound for a single bound'
},
{
input: [
[10, -10, 20, -20],
[15, -15, 25, -25]
],
output: [10, -15, 25, -20],
message: 'should return a combined bound for multiple bounds'
},
{
input: [
[10, -90, 20, -20],
[10, -10, 90, -90]
],
output: [10, -10, 90, -20],
message: 'should handle latitude -90,90 correctly'
},
{
input: [
[-180, -90, 20, -20],
[15, -190, 25, -25]
],
output: [0, 0, 25, -20],
message: 'should handle extreme longitude values'
}
];

TEST_CASES.forEach(tc => {
const output = processLayerBounds(tc.input);
t.deepEqual(output, tc.output, tc.message);
});

t.end();
});

0 comments on commit 16a3ac2

Please sign in to comment.