Claude-skill-registry cesium-expert
CesiumJS 3D 지도 전문가. "지도", "Cesium", "3D 맵", "GIS" 관련 질문 시 사용.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cesium-expert" ~/.claude/skills/majiayu000-claude-skill-registry-cesium-expert && rm -rf "$T"
manifest:
skills/data/cesium-expert/SKILL.mdsource content
Cesium 전문가
$ARGUMENTS CesiumJS 관련 질문에 답변하고 구현을 도와드립니다.
@pf-dev/map 패키지 구조
packages/map/src/ ├── components/ │ ├── MapViewer.tsx # 메인 뷰어 컴포넌트 │ ├── Imagery.tsx # 이미지 레이어 │ ├── Terrain.tsx # 지형 │ └── Tiles3D.tsx # 3D 타일셋 ├── stores/ │ ├── useMapStore.ts # 지도 상태 │ ├── useCameraStore.ts # 카메라 상태 │ └── useFeatureStore.ts # Feature 관리 ├── hooks/ │ └── useCamera.ts # 카메라 제어 └── types/ └── index.ts
주요 패턴
MapViewer 사용
import { MapViewer, Imagery, Terrain } from "@pf-dev/map"; function Map() { return ( <MapViewer options={{ baseLayerPicker: false, geocoder: false, }} > <Imagery provider="vworld" /> <Terrain provider="cesium-world" /> </MapViewer> ); }
카메라 제어
import { useCameraStore } from "@pf-dev/map"; function Controls() { const { flyTo, lookAt, zoomTo } = useCameraStore(); const handleFlyToSeoul = () => { flyTo({ destination: Cesium.Cartesian3.fromDegrees(126.9780, 37.5665, 10000), duration: 2, }); }; return <button onClick={handleFlyToSeoul}>서울로 이동</button>; }
Feature 관리
import { useFeatureStore } from "@pf-dev/map"; function FeatureManager() { const { addEntity, removeEntity, findByProperty } = useFeatureStore(); const addMarker = (position: Cesium.Cartesian3) => { addEntity({ id: `marker-${Date.now()}`, position, billboard: { image: "/marker.png", scale: 1, }, properties: { type: "cctv", name: "CCTV 1", }, }); }; const findCCTVs = () => { return findByProperty("type", "cctv"); }; }
자주 묻는 질문
Q: 성능이 느려요
A: 최적화 방법
설정 (필요할 때만 렌더)requestRenderMode: true- 3D 타일셋 LOD 설정
- 엔티티 수 제한 (1000개 이상이면 Primitive 사용)
로 숨긴 엔티티 정리show: false
<MapViewer options={{ requestRenderMode: true, maximumRenderTimeChange: Infinity, }} />
Q: 이미지 레이어 안 보여요
A: 토큰 확인
VITE_ION_CESIUM_ACCESS_TOKEN=your-token VITE_VWORLD_API_KEY=your-key
Q: 카메라가 지하로 들어가요
A: 지형 충돌 설정
viewer.scene.globe.depthTestAgainstTerrain = true; viewer.scene.screenSpaceCameraController.enableCollisionDetection = true;
Q: 클릭 이벤트 처리
import { useMapStore } from "@pf-dev/map"; function ClickHandler() { const viewer = useMapStore(state => state.viewer); useEffect(() => { if (!viewer) return; const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction((click: { position: Cesium.Cartesian2 }) => { const picked = viewer.scene.pick(click.position); if (Cesium.defined(picked)) { console.log("Picked:", picked.id); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); return () => handler.destroy(); }, [viewer]); }
좌표 변환
// 위경도 → Cartesian3 const position = Cesium.Cartesian3.fromDegrees(126.9780, 37.5665, 100); // Cartesian3 → 위경도 const cartographic = Cesium.Cartographic.fromCartesian(position); const lng = Cesium.Math.toDegrees(cartographic.longitude); const lat = Cesium.Math.toDegrees(cartographic.latitude); const height = cartographic.height; // 화면 좌표 → Cartesian3 const cartesian = viewer.camera.pickEllipsoid( screenPosition, viewer.scene.globe.ellipsoid );
3D 타일셋 로딩
import { Tiles3D } from "@pf-dev/map"; <Tiles3D url="/tiles/building/tileset.json" onReady={(tileset) => { viewer.zoomTo(tileset); }} style={{ color: { conditions: [ ["${height} > 100", "color('red')"], ["true", "color('white')"], ], }, }} />
Context7 참고
CesiumJS 최신 API가 필요하면 Context7로 조회하세요.