Same expression in CircleLayer (works, because it gets removed when is not a cluster) but in HeatMapLayer is not working and I wanted to use it as a cluster mark.
This line in HeatmapLayer **filter={["has", "point_count"]}** also appearing on each marker if its not a cluster.
Mapbox Implementation
Mapbox
Mapbox Version
10.1.27
React Native Version
0.74.2
Platform
iOS
@rnmapbox/maps
version10.0.0-beta.11
Standalone component to reproduce
import React, { useState, useCallback, useEffect, useRef } from "react"; import Mapbox, { Camera, CircleLayer, HeatmapLayer, Images, Image, LocationPuck, MapView, ShapeSource, SymbolLayer, } from "@rnmapbox/maps"; import DogIcon from "@/assets/images/dog-icon.png"; import { FontAwesome6 } from "@expo/vector-icons"; import { StyleSheet, Text, View, Image as RNImage, TouchableOpacity, } from "react-native"; import { useLocation } from "@/components/hooks/location"; import { Tables } from "@/database.types"; import { useFetchLostPets } from "@/api/lost"; import { MapState } from "@rnmapbox/maps/lib/typescript/src/components/MapView"; import { OnPressEvent } from "@rnmapbox/maps/lib/typescript/src/types/OnPressEvent"; import { getThumbnailUrlFromMultimediaUrl } from "@/utils/imageWork"; import { featureCollection, point } from "@turf/helpers";
Mapbox.setAccessToken(process.env.EXPO_PUBLIC_MAPBOX_ACCESS_TOKEN || ""); Mapbox.setTelemetryEnabled(false);
const INITIAL_DEFAULT_REGION = { latitude: -32.94682, longitude: -60.63972, latitudeDelta: 0.2, longitudeDelta: 0.2, };
type PostType = | (Tables<"lost_found"> & { lost_found_multimedia?: { multimedia_url: string }[]; }) | null; type SectionType = "pets" | "medical";
const earthRadius = 6371; // Radius of the Earth in kilometers
// COMPONENT const Map = () => { const { location } = useLocation(); // Assuming this hook provides the user's location
const { data: lostPets = [], error, isLoading, } = useFetchLostPets("Rosario", true);
if (error) { return (
} const [selectedMarker, setSelectedMarker] = useState();
const [section, setSection] = useState("pets");
const [zoomLevel, setZoomLevel] = useState(13);
const { latitude = null, longitude = null } = location.coords || {};
const myLocation = { latitude, longitude, latitudeDelta: 0.2, longitudeDelta: 0.2, } || INITIAL_DEFAULT_REGION;
const actualRegion = useRef(myLocation); const mapRef = useRef<Mapbox.MapView | null>(null); // Ref for MapView component const cameraRef = useRef(null);
const POSTS_IN_MAP =
section === "pets"
? lostPets.filter((pet) => pet.latitude && pet.longitude)
: [];
const onMarkerSelected = (event: OnPressEvent) => {
};
const onVisitMarkerHandler = useCallback(() => { console.log("Visiting marker..."); }, []);
const deltaToKilometers = (delta: number) => Math.floor((delta / 360) * 40075);
const onRegionChangeComplete = (newRegion: MapState) => { setZoomLevel(newRegion.properties.zoom); };
const handleMapReady = useCallback(() => { console.log("Map is ready!"); }, []);
const onChangeCategoryHandler = useCallback( (section: SectionType) => () => { setSelectedMarker(null); setSection(section); }, [setSelectedMarker, setSection] );
const closeSelectedMarker = () => { setSelectedMarker(null); }; const markers = POSTS_IN_MAP.map((marker) => point([marker.longitude!!, marker.latitude!!], { marker }) );
console.log( "🚀 ~ file: MapBox.tsx:242 ~ onMarkerSelected ~ markers==>", markers ); console.log("FEATURE COLLECTION", featureCollection(markers).features[0]); return (
); };
const styles = StyleSheet.create({ markerTitle: { width: "100%", fontSize: 14, }, marker: { borderWidth: 0, }, markerImageInMap: { width: 30, height: 30, borderRadius: 15, }, selectedMarker: { borderWidth: 1, borderColor: "gray", borderRadius: 25, }, selectedMarkerImageInMap: { width: 50, height: 50, borderRadius: 25, }, areaToShownText: { color: "gray", fontWeight: "600", }, iconFiltersContainer: { flexDirection: "column", backgroundColor: "white", borderRadius: 10, position: "absolute", bottom: 10, left: 10, padding: 10, height: "auto", gap: 10, alignContent: "center", justifyContent: "space-between", }, iconFilterTextBox: { flexDirection: "row", justifyContent: "center", color: "gray", }, iconFilterText: { textAlign: "center", color: "gray", letterSpacing: 1, }, iconFiltersBox: { flexDirection: "row", justifyContent: "space-evenly", gap: 15, paddingHorizontal: 2, height: 30, }, iconFilterDefault: { color: "gray", }, iconFilterSelected: { color: "red", }, selectedMarkerDetails: { position: "absolute", bottom: 90, left: 0, right: 0, backgroundColor: "white", padding: 10, alignItems: "center", borderRadius: 10, }, selectedMarkerImage: { width: 100, height: 100, borderRadius: 10, }, selectedMarkerTitle: { fontSize: 16, fontWeight: "bold", marginTop: 10, }, closeButton: { marginTop: 10, padding: 10, backgroundColor: "red", borderRadius: 5, }, closeButtonText: { color: "white", fontWeight: "bold", }, });
export default Map;
Observed behavior and steps to reproduce
Same expression in CircleLayer (works, because it gets removed when is not a cluster) but in HeatMapLayer is not working and I wanted to use it as a cluster mark.
<ShapeSource id="losts_founds" shape={featureCollection(markers)} cluster={true} clusterRadius={50} clusterMaxZoomLevel={15} onPress={(event) => onMarkerSelected(event)}
Expected behavior
not to show the heatmaplayer if is not a cluster.
Notes / preliminary analysis
No response
Additional links and references
No response