Skip to content

Commit

Permalink
FIX: Prevent crash in react-map-gl when zoom cannot be calculated
Browse files Browse the repository at this point in the history
Signed-off-by: Ilija Puaca <ilija@unfolded.ai>
  • Loading branch information
ilijapuaca authored and heshan0131 committed Dec 7, 2020
1 parent 027985a commit 341e77a
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 34 deletions.
13 changes: 6 additions & 7 deletions src/components/geocoder-panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,18 +135,17 @@ export default function GeocoderPanelFactory() {
lon + GEOCODER_GEO_OFFSET,
lat + GEOCODER_GEO_OFFSET
];
const {zoom} = geoViewport.viewport(bounds, [
const centerAndZoom = geoViewport.viewport(bounds, [
this.props.mapState.width,
this.props.mapState.height
]);
// center being calculated by geo-vieweport.viewport has a complex logic that
// projects and then unprojects the coordinates to determine the center
// Calculating a simple average instead as that is the expected behavior in most of cases
const center = [(bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2];

this.props.updateMap({
latitude: center[1],
longitude: center[0],
latitude: centerAndZoom.center[1],
longitude: centerAndZoom.center[0],
// For marginal or invalid bounds, zoom may be NaN. Make sure to provide a valid value in order
// to avoid corrupt state and potential crashes as zoom is expected to be a number
...(Number.isFinite(centerAndZoom.zoom) ? {zoom: centerAndZoom.zoom} : {}),
zoom,
pitch: 0,
bearing: 0,
Expand Down
26 changes: 9 additions & 17 deletions src/components/plot-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,23 +173,15 @@ export default function PlotContainerFactory(MapContainer) {
};

if (exportImageSetting.center) {
const getViewport = shouldCenter => {
if (shouldCenter) {
const {zoom} = geoViewport.viewport(bounds, [width, height]);
// center being calculated by geo-vieweport.viewport has a complex logic that
// projects and then unprojects the coordinates to determine the center
// Calculating a simple average instead as that is the expected behavior in most of cases
const center = [(bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2];
return {center, zoom};
}

return {center: [mapState.longitude, mapState.latitude], zoom: mapState.zoom};
};

const {center, zoom} = getViewport(exportImageSetting.center);

newMapState.longitude = center[0];
newMapState.latitude = center[1];
const viewport = exportImageSetting.center
? geoViewport.viewport(bounds, [width, height])
: {center: [newMapState.longitude, newMapState.latitude], zoom: mapState.zoom};
// For marginal or invalid bounds, zoom may be NaN. Make sure to provide a valid value in order
// to avoid corrupt state and potential crashes as zoom is expected to be a number
const zoom = viewport.zoom || mapState.zoom;

newMapState.longitude = viewport.center[0];
newMapState.latitude = viewport.center[1];
newMapState.zoom = zoom + Number(Math.log2(scale) || 0);
}

Expand Down
19 changes: 9 additions & 10 deletions src/reducers/map-state-updaters.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,19 @@ export const updateMapUpdater = (state, action) => ({
export const fitBoundsUpdater = (state, action) => {
const bounds = validateBounds(action.payload);
if (!bounds) {
Console.warn('invalid map bounds provided')
Console.warn('invalid map bounds provided');
return state;
}
const {zoom} = geoViewport.viewport(bounds, [state.width, state.height]);
// center being calculated by geo-vieweport.viewport has a complex logic that
// projects and then unprojects the coordinates to determine the center
// Calculating a simple average instead as that is the expected behavior in most of cases
const center = [(bounds[0] + bounds[2]) / 2, (bounds[1] + bounds[3]) / 2];
}

const viewport = geoViewport.viewport(bounds, [state.width, state.height]);

return {
...state,
latitude: center[1],
longitude: center[0],
zoom
latitude: viewport.center[1],
longitude: viewport.center[0],
// For marginal or invalid bounds, zoom may be NaN. Make sure to provide a valid value in order
// to avoid corrupt state and potential crashes as zoom is expected to be a number
...(Number.isFinite(viewport.zoom) ? {zoom: viewport.zoom} : {})
};
};

Expand Down

0 comments on commit 341e77a

Please sign in to comment.