Open Denissavv opened 8 months ago
This is most likely an issue with your rendering of map markers - unsure what else could be causing this issue without seeing the code.
Sorry for my poor question, let me try to show you the whole implementation:
im using import { YaMap } from 'react-native-yamap';
the thing is - there is no latitudeDelta and longitudeDelta after changing position of maps camera, so I calculated myself.
export const getRegionForZoom = (lat: number, lon: number, zoom: number): MapRegion => {
const distanceDelta = Math.exp(Math.log(360) - zoom * Math.LN2);
const { width, height } = Dimensions.get('window');
const aspectRatio = width / height;
return {
latitude: lat,
longitude: lon,
latitudeDelta: distanceDelta * aspectRatio,
longitudeDelta: distanceDelta,
};
}
const [westLng, setWestLng] = useState(INITIAL_WEST_LNG);
const [southLat, setSouthLat] = useState(INITIAL_SOUTH_LAT);
const [eastLng, setEastLng] = useState(INITIAL_EAST_LNG);
const [northLat, setNorthLat] = useState(INITIAL_NORTH_LAT);
const convertedArray: IFeature[] = points
.filter((data) => data.location.longitude !== '0' || data.location.latitude !== '0')
.map((item) => ({
type: 'Feature' as const,
geometry: {
type: 'Point' as const,
coordinates: [+item.location.longitude, +item.location.latitude],
},
properties: {
...item,
...item.location,
...item.owner,
id: item._id,
data: item,
},
}));
const superCluster = new Supercluster(superclusterOptions);
superCluster.load(convertedArray);
const clustersAndPoints = superCluster.getClusters([westLng, southLat, eastLng, northLat], zoom);
my render is looks like:
return (
<YaMap
ref={mapRef}
logoPadding={{ vertical: 670, horizontal: 30 }}
showUserPosition={false}
initialRegion={{ lon: MoscowPoint.lon, lat: MoscowPoint.lat }}
style={RN.StyleSheet.absoluteFillObject}
onLayout={() => setMapIsReady(true)}
onCameraPositionChangeEnd={(event) => {
if (event.nativeEvent.finished) {
setWestLng(INITIAL_WEST_LNG);
setSouthLat(INITIAL_SOUTH_LAT);
setEastLng(INITIAL_EAST_LNG);
setNorthLat(INITIAL_NORTH_LAT);
mapRef.current?.getCameraPosition((position) => {
const { lat, lon } = position.point;
const { zoom } = position;
handleChangeRegion({
...getRegionForZoom(lat, lon, zoom),
});
handleChangeZoom(position.zoom);
});
}
}}
>
<UserLocationMarker />
<Clusterer
data={clustersAndPoints}
region={region}
options={{
radius: 20,
extent: 600,
minPoints: 3,
minZoom: 0,
}}
mapDimensions={MAP_DIMENSIONS}
renderItem={(item) => {
const clusterId: number = item.properties?.cluster && item.properties?.cluster_id;
const markerId: string = item.properties?.id;
return (
<ClusterAndMarkerPoint
points={clustersAndPoints}
clusterId={clusterId}
markerId={markerId}
item={item}
onPress={
item?.properties?.cluster &&
item?.properties?.cluster_id !== null &&
(() => {
const clusterId = item?.properties?.cluster_id;
const clusterArr: Array<number> = clustersAndPoints.map((data) => data.properties.cluster_id);
const isClusterExist = clusterArr.includes(clusterId);
const toCluster = {
lon: item?.geometry?.coordinates[0],
lat: item?.geometry?.coordinates[1],
};
if (clusterId !== undefined && isClusterExist) {
getClusterZoom(clusterId);
} else {
if (zoom < 7) {
handleChangeZoom(7, toCluster, 0.6);
} else if (zoom < 10 && zoom > 7) {
handleChangeZoom(10, toCluster, 0.6);
} else {
handleChangeZoom(zoom + 3, toCluster, 0.6);
}
console.warn(`No cluster with the specified id: ${clusterId}`);
}
})
}
/>
);
}}
/>
</YaMap>
)
and my ClusterAndMarkerPoint:
export const ClusterAndMarkerPoint: FunctionComponent<Props> = memo(
({ item, onPress, clusterId, markerId, points }) => {
const [logoLoaded, setLogoLoaded] = React.useState(false);
const clusterArr: Array<number> = points.map((data) => data.properties.cluster_id);
const handlePress = useRecoilCallback(
({ get, set, reset }) =>
(id: string) => {
if (get(openedChargePointAtom)) {
return;
}
set(openedChargePointAtom, id);
chargersScreenBottomSheetsShowablePortal.current?.show(
`DetailedChargePoint(id=${id})`,
DetailedStationSheet,
{
chargePointId: id,
onClose: () => {
reset(openedChargePointAtom);
mapRef.current?.getCameraPosition((position) => {
if (position.zoom > 10) {
mapRef.current?.setZoom(position.zoom - 1, 2, 1);
} else {
mapRef.current?.setZoom(position.zoom, 2, 1);
}
});
},
}
);
},
[]
);
return (
<YaMarker
source={item?.properties?.logo_url && { uri: item?.properties?.logo_url }}
key={clusterId || `${markerId + logoLoaded}`}
point={{
lat: +item.geometry.coordinates[1] || Number(item?.properties?.latitude),
lon: +item.geometry.coordinates[0] || Number(item?.properties?.longitude),
}}
onPress={onPress || (() => handlePress(item?.properties?.id))}
>
{item?.properties?.cluster && clusterId ? (
<ClusterComponent key={clusterId} clusterArr={clusterArr} item={item} />
) : (
<>
{item?.properties?.logo_url && (
<PointComponent
key={`${markerId + logoLoaded}`}
markerId={markerId}
logoUrl={item?.properties?.logo_url}
logoLoaded={logoLoaded}
setLogoLoaded={setLogoLoaded}
/>
)}
</>
)}
</YaMarker>
);
},
(prevProps, nextProps) =>
prevProps.item.properties?.cluster_id === nextProps.item.properties?.cluster_id &&
prevProps.item.properties?.id === nextProps.item.properties?.id &&
prevProps.item.properties?.point_count === nextProps.item.properties?.point_count &&
prevProps.item.properties?.onPress === nextProps.item.properties?.onPress &&
prevProps.item.properties?.getClusterExpansionRegion === nextProps.item.properties?.getClusterExpansionRegion &&
prevProps.markerId === nextProps.markerId &&
prevProps.clusterId === nextProps.clusterId
);
When I zoom-in or zoom-out, some points feels like trying to become cluster, but turn on into a little blue points.
When I add key (as it shown in the example - key={item.properties?.cluster_id ??
point-${item.properties?.id}
} - blue points appear, when I remove key - the issue is fix, but I guess that clusters and points re-render every map changing position.