import MapView from "react-native-map-clustering";
<MapView
ref={mapRef}
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={region || initialRegion}
customMapStyle={isDarkMode ? mapStyle : null}
userInterfaceStyle={isDarkMode ? 'dark' : 'light'}
onRegionChangeComplete={handleRegionChangeComplete}
showsBuildings={true}
onMapReady={() => {
InteractionManager.runAfterInteractions(() => {
setIsMapReady(true);
});
}}
showsUserLocation={true}
clusterColor={colors.blue}
clusterTextColor={colors.white}
clusterFontSize={12}
clusterFontWeight={fonts.bold}
clusteringEnabled={true}
>
{isMapReady && (
)}
import React from 'react';
import { View } from 'react-native';
import { Marker } from 'react-native-maps';
import FastImage from '@d11/react-native-fast-image';
import { handleOverlappingMarkers } from 'src/utils/map/handleOverlappingMarkers';
const MapMarkers = ({ selectedBottomTab, onMarkerPress, mapsData }) => {
const eventsData =
selectedBottomTab === 'events'
? Array.isArray(mapsData)
? mapsData
: mapsData?.events?.items || []
: mapsData?.events?.items || [];
const placesData =
selectedBottomTab === 'places'
? Array.isArray(mapsData)
? mapsData
: mapsData?.places?.items || []
: mapsData?.places?.items || [];
const markers =
selectedBottomTab === 'all'
? [
...eventsData.map(event => ({
...event,
type: 'event',
})),
...placesData.map(place => ({
...place,
type: 'place',
})),
]
: selectedBottomTab === 'events'
? eventsData.map(event => ({
...event,
type: 'event',
}))
: placesData.map(place => ({ ...place, type: 'place' }));
const adjustedMarkers = handleOverlappingMarkers(markers, {
offset: 0.0001,
spiral: false,
});
const validMarkers = adjustedMarkers.filter(marker => {
const isEvent = marker.type === 'event';
let coordinates;
if (isEvent) {
// Use only basicInfo.venueLocation.coordinates for events
coordinates = marker?.basicInfo?.venueLocation?.coordinates;
} else {
// For places
coordinates = marker?.location?.coordinates;
}
if (!Array.isArray(coordinates) || coordinates.length < 2) {
console.warn('Marker missing coordinates:', {
id: marker?._id || marker?.id,
name: marker?.basicInfo?.title || marker?.name,
});
return false;
}
const latitude = coordinates[1];
const longitude = coordinates[0];
if (typeof latitude !== 'number' || typeof longitude !== 'number') {
console.warn('Marker has invalid coordinate types:', {
id: marker?._id || marker?.id,
latitude: typeof latitude,
longitude: typeof longitude,
});
return false;
}
return true;
});
return validMarkers.map(marker => {
const isEvent = marker.type === 'event';
let coordinates;
if (isEvent) {
coordinates = marker?.basicInfo?.venueLocation?.coordinates;
} else {
coordinates = marker?.location?.coordinates;
}
const latitude = coordinates[1];
const longitude = coordinates[0];
const imageUrl =
(isEvent ? marker?.basicInfo?.media : null) ||
marker?.basicInfo?.media?.logo;
const baseSize = isEvent ? 81 : 58;
return (
<Marker
key={marker?._id || marker?.id}
identifier={marker?._id || marker?.id}
coordinate={{ latitude, longitude }}
tracksViewChanges={false}
onPress={() => {
onMarkerPress(marker);
}}
>
{imageUrl ? (
<FastImage
source={{ uri: imageUrl }}
style={{
width: baseSize,
height: baseSize,
borderRadius: isEvent ? 5 : 29,
backgroundColor: 'transparent',
}}
resizeMode={FastImage.resizeMode.cover}
/>
) : (
<View
style={{
width: baseSize,
height: baseSize,
borderRadius: isEvent ? 5 : 29,
backgroundColor: '#D9D9D9',
}}
/>
)}
</Marker>
);
});
};
export default MapMarkers;
"react-native-map-clustering": "^4.0.0",
"react-native-maps": "^1.26.17",
"react-native": "0.80.1",
import MapView from "react-native-map-clustering";
<MapView
ref={mapRef}
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={region || initialRegion}
customMapStyle={isDarkMode ? mapStyle : null}
userInterfaceStyle={isDarkMode ? 'dark' : 'light'}
onRegionChangeComplete={handleRegionChangeComplete}
showsBuildings={true}
onMapReady={() => {
InteractionManager.runAfterInteractions(() => {
setIsMapReady(true);
});
}}
showsUserLocation={true}
clusterColor={colors.blue}
clusterTextColor={colors.white}
clusterFontSize={12}
clusterFontWeight={fonts.bold}
clusteringEnabled={true}
>
{isMapReady && (
)}
import React from 'react';
import { View } from 'react-native';
import { Marker } from 'react-native-maps';
import FastImage from '@d11/react-native-fast-image';
import { handleOverlappingMarkers } from 'src/utils/map/handleOverlappingMarkers';
const MapMarkers = ({ selectedBottomTab, onMarkerPress, mapsData }) => {
const eventsData =
selectedBottomTab === 'events'
? Array.isArray(mapsData)
? mapsData
: mapsData?.events?.items || []
: mapsData?.events?.items || [];
const placesData =
selectedBottomTab === 'places'
? Array.isArray(mapsData)
? mapsData
: mapsData?.places?.items || []
: mapsData?.places?.items || [];
const markers =
selectedBottomTab === 'all'
? [
...eventsData.map(event => ({
...event,
type: 'event',
})),
...placesData.map(place => ({
...place,
type: 'place',
})),
]
: selectedBottomTab === 'events'
? eventsData.map(event => ({
...event,
type: 'event',
}))
: placesData.map(place => ({ ...place, type: 'place' }));
const adjustedMarkers = handleOverlappingMarkers(markers, {
offset: 0.0001,
spiral: false,
});
const validMarkers = adjustedMarkers.filter(marker => {
const isEvent = marker.type === 'event';
let coordinates;
});
return validMarkers.map(marker => {
const isEvent = marker.type === 'event';
});
};
export default MapMarkers;
"react-native-map-clustering": "^4.0.0",
"react-native-maps": "^1.26.17",
"react-native": "0.80.1",