Loading...
Loading...
CesiumJS 3D 지도 전문가. "지도", "Cesium", "3D 맵", "GIS" 관련 질문 시 사용.
npx skill4agent add pluxity/pf-frontend cesium-expertpackages/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.tsimport { 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.978, 37.5665, 10000),
duration: 2,
});
};
return <button onClick={handleFlyToSeoul}>서울로 이동</button>;
}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");
};
}requestRenderMode: trueshow: false<MapViewer
options={{
requestRenderMode: true,
maximumRenderTimeChange: Infinity,
}}
/>VITE_ION_CESIUM_ACCESS_TOKEN=your-token
VITE_VWORLD_API_KEY=your-keyviewer.scene.globe.depthTestAgainstTerrain = true;
viewer.scene.screenSpaceCameraController.enableCollisionDetection = true;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.978, 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);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')"],
],
},
}}
/>;