Geographic utility functions for coordinate transformations, bounds calculations, and geographic computations. These functions work independently of the main GoogleMap component and can be used for geographic calculations in any context.
Calculate optimal map center and zoom to fit geographic bounds within specified dimensions.
/**
* Calculates the optimal center and zoom level to fit given bounds within specified dimensions
* @param bounds - Geographic bounds in nw/se or ne/sw format
* @param size - Container dimensions
* @returns Object with center, zoom, and calculated bounds
*/
function fitBounds(
bounds: BoundsInput,
size: { width: number; height: number }
): FitBoundsResult;
type BoundsInput =
| { nw: { lat: number; lng: number }; se: { lat: number; lng: number } }
| { ne: { lat: number; lng: number }; sw: { lat: number; lng: number } };
interface FitBoundsResult {
center: { lat: number; lng: number };
zoom: number;
newBounds: {
nw: { lat: number; lng: number };
se: { lat: number; lng: number };
ne: { lat: number; lng: number };
sw: { lat: number; lng: number };
};
}Usage Examples:
import { fitBounds } from 'google-map-react';
// Using nw/se format
const bounds1 = {
nw: { lat: 50.01038826014866, lng: -118.6525866875 },
se: { lat: 32.698335045970396, lng: -92.0217273125 }
};
// Using ne/sw format
const bounds2 = {
ne: { lat: 50.01038826014866, lng: -92.0217273125 },
sw: { lat: 32.698335045970396, lng: -118.6525866875 }
};
const size = { width: 800, height: 600 };
const result = fitBounds(bounds1, size);
console.log(result.center); // { lat: ..., lng: ... }
console.log(result.zoom); // optimal zoom level
// Use with GoogleMapReact
<GoogleMapReact
center={result.center}
zoom={result.zoom}
// ... other props
/>Convert between different bounds format conventions.
/**
* Converts northeast/southwest bounds format to northwest/southeast format
* @param bounds - Bounds in ne/sw format
* @returns Bounds in nw/se format
*/
function convertNeSwToNwSe(bounds: {
ne: { lat: number; lng: number };
sw: { lat: number; lng: number };
}): {
nw: { lat: number; lng: number };
se: { lat: number; lng: number };
};
/**
* Converts northwest/southeast bounds format to northeast/southwest format
* @param bounds - Bounds in nw/se format
* @returns Bounds in ne/sw format
*/
function convertNwSeToNeSw(bounds: {
nw: { lat: number; lng: number };
se: { lat: number; lng: number };
}): {
ne: { lat: number; lng: number };
sw: { lat: number; lng: number };
};Usage Examples:
import { convertNeSwToNwSe, convertNwSeToNeSw } from 'google-map-react';
// Convert from ne/sw to nw/se
const neSwBounds = {
ne: { lat: 40.7831, lng: -73.9712 },
sw: { lat: 40.7489, lng: -74.0059 }
};
const nwSeBounds = convertNeSwToNwSe(neSwBounds);
// Result: { nw: { lat: 40.7831, lng: -74.0059 }, se: { lat: 40.7489, lng: -73.9712 } }
// Convert back
const convertedBack = convertNwSeToNeSw(nwSeBounds);
// Result matches original neSwBoundsConvert between meters and screen pixels for marker sizing and distance calculations.
/**
* Converts meters to screen pixels for given coordinates and zoom level
* @param meters - Distance in meters
* @param center - Center coordinates for calculation
* @param zoom - Map zoom level
* @returns Width and height in screen pixels
*/
function meters2ScreenPixels(
meters: number,
center: { lat: number; lng: number },
zoom: number
): { w: number; h: number };Usage Examples:
import { meters2ScreenPixels } from 'google-map-react';
// Calculate how many pixels represent 1000 meters at different locations
const center1 = { lat: 40.7128, lng: -74.0060 }; // New York
const center2 = { lat: 0, lng: 0 }; // Equator
const pixelsNY = meters2ScreenPixels(1000, center1, 15);
const pixelsEquator = meters2ScreenPixels(1000, center2, 15);
console.log('1000m in NYC:', pixelsNY); // { w: 76.4, h: 76.4 }
console.log('1000m at equator:', pixelsEquator); // { w: 97.2, h: 97.2 }
// Use for marker sizing
const markerSize = meters2ScreenPixels(500, center, zoom);
const MarkerComponent = ({ size }) => (
<div style={{
width: size.w,
height: size.h,
backgroundColor: 'red',
borderRadius: '50%'
}} />
);
<GoogleMapReact
center={center}
zoom={zoom}
>
<MarkerComponent
lat={center.lat}
lng={center.lng}
size={markerSize}
/>
</GoogleMapReact>Automatically fit map to show all markers:
import { fitBounds } from 'google-map-react';
function MapWithMarkers({ markers }) {
// Calculate bounds from marker positions
const bounds = markers.reduce((acc, marker) => {
return {
nw: {
lat: Math.max(acc.nw.lat, marker.lat),
lng: Math.min(acc.nw.lng, marker.lng)
},
se: {
lat: Math.min(acc.se.lat, marker.lat),
lng: Math.max(acc.se.lng, marker.lng)
}
};
}, {
nw: { lat: -90, lng: 180 },
se: { lat: 90, lng: -180 }
});
const { center, zoom } = fitBounds(bounds, { width: 800, height: 600 });
return (
<GoogleMapReact
center={center}
zoom={zoom}
>
{markers.map(marker => (
<Marker key={marker.id} lat={marker.lat} lng={marker.lng} />
))}
</GoogleMapReact>
);
}Size markers based on geographic scale:
import { meters2ScreenPixels } from 'google-map-react';
function ResponsiveMarker({ lat, lng, radiusMeters, zoom }) {
const center = { lat, lng };
const size = meters2ScreenPixels(radiusMeters * 2, center, zoom);
return (
<div style={{
width: size.w,
height: size.h,
backgroundColor: 'blue',
borderRadius: '50%',
transform: 'translate(-50%, -50%)'
}} />
);
}
// Usage
<GoogleMapReact zoom={zoom} onChange={({ zoom }) => setZoom(zoom)}>
<ResponsiveMarker
lat={40.7128}
lng={-74.0060}
radiusMeters={1000}
zoom={zoom}
/>
</GoogleMapReact>