[Bug] GoogleMapsOverlay crashes when a vector map is temporarily zero-width
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 14.6k
- Forks
- 2.3k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 42
Description
Description
Hi! We found a crash in GoogleMapsOverlay when Google Maps briefly reports a vector map with zero width and a positive height.
getViewPropsFromCoordinateTransformer calculates aspect = 0 for that frame. Deck cannot invert the resulting projection matrix, and the reused MapView then throws TypeError: Cannot read properties of null (reading '0').
I reproduced this in deck.gl 9.3.10 and current master at 4059257667f07b379f4c5f019eb88ea20260d5c5 using deck.gl's Google Maps mock and the overlay's normal lifecycle. This resembles #4218, though it occurs in the vector-map coordinate transformer.
Flavors
GoogleMapsOverlay
Expected Behavior
A draw should not throw while either map dimension is zero. Once the map has a visible size again, the next draw can restore the correct projection.
Steps to Reproduce
Add this test to test/modules/google-maps/google-maps-overlay.spec.ts:
test('GoogleMapsOverlay#draw tolerates a zero-width vector map', async () => {
const map = new mapsApi.Map({
width: 0,
height: 600,
longitude: -122.45,
latitude: 37.78,
zoom: 13,
renderingType: mapsApi.RenderingType.VECTOR
});
let resolveDeviceInitialized = () => {};
const deviceInitialized = new Promise<void>(resolve => {
resolveDeviceInitialized = resolve;
});
const overlay = new GoogleMapsOverlay({
device,
interleaved: false,
onDeviceInitialized: () => resolveDeviceInitialized(),
layers: [
new ScatterplotLayer({
data: [{position: [-122.45, 37.78]}],
getPosition: datum => datum.position,
radiusMinPixels: 10
})
]
});
overlay.setMap(map);
await deviceInitialized;
try {
expect(() => map.draw()).not.toThrow();
} finally {
overlay.finalize();
}
});
Run:
yarn vitest run --project=headless test/modules/google-maps/google-maps-overlay.spec.ts -t "zero-width vector map"
The test logs deck: Pixel project matrix not invertible and fails with TypeError: Cannot read properties of null (reading '0').
I also ran the mounted overlay through 800x600, 800x0, 0x0, 0x600, and back to 800x600. The current code accepts the zero-height and fully hidden states, then throws at 0x600.
The current calculation guards the height only:
const aspect = height ? width / height : 1;
Guarding both dimensions prevents the invalid projection:
const aspect = width > 0 && height > 0 ? width / height : 1;
After this change, all five size transitions succeed. All 11 tests in google-maps-overlay.spec.ts, including the regression test, pass on 9.3.10 and current master.
Environment
- Framework version: deck.gl 9.3.10 and
masterat4059257667f07b379f4c5f019eb88ea20260d5c5 - Browser: Chromium 147 through deck.gl's headless Vitest project
- OS: macOS
Logs
deck: Pixel project matrix not invertible
TypeError: Cannot read properties of null (reading '0')
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in the vector-map coordinate transformer used by GoogleMapsOverlay and inspect getViewPropsFromCoordinateTransformer, especially its aspect calculation. Run yarn vitest run --project=headless test/modules/google-maps/google-maps-overlay.spec.ts -t "zero-width vector map" and verify that the regression test and all 11 tests pass without a draw-time exception during zero-sized map states.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 90/100