Open ParkJongJoon7128 opened 6 days ago
예제의 App.tsx
의 코드를 그대로 쓰신 것으로 보입니다. clusters
변수가 hash
가 변할 때만 변경되도록 설정되어 있으니 useMemo
를 지워보시면 될것같습니다.
현재 저는 서버로 요청을 보내 받아온 결과값을 restaurants
라는 state 변수에 저장하여 marker로 뿌려주고 있습니다(빨간 사각형이 응답값으로 내려온 데이터 좌표값들).
이 state 변수와 연관지어 clusters
를 보여줄순 없나요? 지도를 축소했을때는 겹치는 마커만큼 갯수를 clusters로 표현하고, 확대하면 clusters가 벗겨져 마커를 띄우게 하고 싶습니다.
현재 구현한 코드입니다.
import { formatJson, generateArray } from '@mj-studio/js-util';
import {
Camera,
ClusterMarkerProp,
MapType,
NaverMapMarkerOverlay,
NaverMapView,
NaverMapViewRef,
Region,
} from '@mj-studio/react-native-naver-map';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { View } from 'react-native';
import { getRestaurants } from '../utils/API/LocationAPI';
import { Restaurant } from '../utils/data/type';
const Cameras = {
KNU: {
latitude: 37.271855,
longitude: 127.127626,
zoom: 14,
},
} satisfies Record<string, Camera>;
const Regions = {
KNU_Region: {
latitude: 37.271855,
longitude: 127.127626,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
},
} satisfies Record<string, Region>;
const MapTypes = [
'Basic',
'Navi',
'Satellite',
'Hybrid',
'Terrain',
'NaviHybrid',
'None',
] satisfies MapType[];
const LocationMapScreen = () => {
// Logic
const ref = useRef<NaverMapViewRef>(null);
const [restaurants, setRestaurants] = useState<Restaurant[]>([]);
const [indoor, setIndoor] = useState(false);
const [mapType, setMapType] = useState<MapType>(MapTypes[0]!);
const [lightness, setLightness] = useState(0);
const [compass, setCompass] = useState(true);
const [scaleBar, setScaleBar] = useState(true);
const [zoomControls, setZoomControls] = useState(true);
const [indoorLevelPicker, setIndoorLevelPicker] = useState(true);
const [myLocation, setMyLocation] = useState(true);
const [hash, setHash] = useState(0);
const [camera, setCamera] = useState(Cameras.KNU);
const clusters = useMemo<
{
markers: ClusterMarkerProp[];
screenDistance?: number;
minZoom?: number;
maxZoom?: number;
animate?: boolean;
width?: number;
height?: number;
}[]
>(() => {
return generateArray(5).map(i => {
return {
width: 200,
height: 200,
markers: generateArray(restaurants.length).map<ClusterMarkerProp>(
j =>
({
image: {
httpUri: `https://picsum.photos/seed/${hash}-${i}-${j}/32/32`,
},
width: 100,
height: 100,
latitude: Cameras.KNU.latitude,
longitude: Cameras.KNU.longitude,
identifier: `${hash}-${i}-${j}`,
} satisfies ClusterMarkerProp),
),
};
});
}, [hash]);
useEffect(() => {
getRestaurants(setRestaurants);
}, []);
// View
return (
<View
style={{
flex: 1,
backgroundColor: 'white',
}}>
<NaverMapView
style={{flex: 1}}
ref={ref}
initialCamera={{
latitude: 37.271855,
longitude: 127.127626,
zoom: 15,
}}
locale="ko"
layerGroups={{
BUILDING: true,
BICYCLE: false,
CADASTRAL: false,
MOUNTAIN: false,
TRAFFIC: false,
TRANSIT: false,
}}
mapType={mapType}
initialRegion={Regions.KNU_Region}
camera={camera}
isIndoorEnabled={indoor}
isShowCompass={compass}
isShowIndoorLevelPicker={indoorLevelPicker}
isShowScaleBar={scaleBar}
isShowZoomControls={zoomControls}
isShowLocationButton={myLocation}
lightness={lightness}
clusters={clusters}
onInitialized={() => console.log('initialized!')}
onTapClusterLeaf={({markerIdentifier}) => {
console.log('onTapClusterLeaf', markerIdentifier);
}}
onTapMap={(args) => console.log(`Map Tapped: ${formatJson(args)}`)}
>
{restaurants.map((restaurant, index) => (
<NaverMapMarkerOverlay
key={restaurant.id}
latitude={parseFloat(restaurant.y)}
longitude={parseFloat(restaurant.x)}
onTap={() => console.log(`Tapped on: ${restaurant.name}`)}
anchor={{x: 0.5, y: 1}}
width={20}
height={20}>
<View style={{width: 50, height: 50, backgroundColor: 'red'}} />
</NaverMapMarkerOverlay>
))}
</NaverMapView>
</View>
);
};
export default LocationMapScreen;
그리고 예제에서는 generateArray()
메소드를 사용하고 계시던데, 이 메소드의 사용법에 대해서도 궁금합니다.
크롤링한 데이터를 기반으로 지도맵에 마커를 뿌려 보여줄려고 하는데, 적은양의 데이터가 아니라서 마커가 많아 겹치는 부분이 많습니다. 때문에 이를 방지하고자 라이브러리에서 클러스터(cluster) 기능을 제공해주고 있어서 사용하고 있는데, 구현을 하고 앱을 실행해보니 클러스터 기능이 적용이 안되고, 마커만 적용되고 있어 질문합니다.
공식문서에서 사용된 예제에서는 클러스터가 사용되어 정상적으로 동작하는것으로 보이는데, 혹시 제 코드에서 미흡하게 구현한 부분이 있으면 조언을 받고 싶어 코드와 시연 영상과 함께 이슈 글을 남깁니다.
https://github.com/user-attachments/assets/55f5a668-24da-4fce-8faf-0c61c32b09b2
제가 구현중인 코드입니다.