UNPKG

vworld-react-3d

Version:

VWorld 3.0 API React Component - 한국 공공데이터 3D 지도 컴포넌트

356 lines (280 loc) 11.1 kB
# VWorld React 3D 한국 공공데이터 VWorld 3.0 API를 React에서 쉽게 사용할 수 있는 컴포넌트 패키지입니다. ## 🚀 설치 ```bash npm install vworld-react-3d # 또는 yarn add vworld-react-3d ``` ## 📖 사용법 ### 기본 사용법 ```tsx import React from "react"; import { VWorldMap } from "vworld-react-3d"; function App() { return ( <div> <h1>VWorld 3D 지도</h1> <VWorldMap config={{ apiKey: "YOUR_VWORLD_API_KEY" }} width="100%" height="600px" onMapReady={(map) => { console.log("맵이 준비되었습니다:", map); }} onMapClick={(coord) => { console.log("클릭 위치:", coord); }} /> </div> ); } ``` ### 고급 사용법 (카메라 제어) ```tsx import React, { useState, useRef } from "react"; import { VWorldMap, getGwanghwamunCameraPosition, createCoordZ, createDirection, createCameraPosition, } from "vworld-react-3d"; function App() { const [mapInstance, setMapInstance] = useState(null); const [cameraPosition, setCameraPosition] = useState(null); // 서울타워로 이동 const moveToSeoulTower = () => { const seoulTower = createCameraPosition( createCoordZ(126.988, 37.551, 1000), // 경도, 위도, 고도 createDirection(0, -30, 0) // heading, pitch, roll ); setCameraPosition(seoulTower); }; // 부산으로 이동 const moveToBusan = () => { const busan = createCameraPosition( createCoordZ(129.075, 35.179, 2000), createDirection(0, -45, 0) ); setCameraPosition(busan); }; return ( <div> <VWorldMap config={{ apiKey: "YOUR_VWORLD_API_KEY" }} options={{ mapId: "vmap", logo: true, navigation: true, backgroundColor: "#f0f0f0", }} initCameraPosition={getGwanghwamunCameraPosition(500)} cameraPosition={cameraPosition} width="100%" height="500px" onMapReady={(map) => { console.log("맵 준비:", map); setMapInstance(map); }} onMapClick={(coord) => { console.log("클릭 위치:", coord); }} onCameraChange={(camera) => { console.log("카메라 변경:", camera); }} /> <div style={{ marginTop: "10px" }}> <button onClick={moveToSeoulTower}>서울타워로 이동</button> <button onClick={moveToBusan}>부산으로 이동</button> </div> </div> ); } ``` ### 맵 인스턴스 직접 제어 ```tsx import React, { useRef } from "react"; import { VWorldMap } from "vworld-react-3d"; function App() { const mapRef = useRef(null); const controlMap = () => { if (mapRef.current) { const map = mapRef.current; // 현재 위치 가져오기 const currentPos = map.getCurrentPosition(); console.log("현재 위치:", currentPos); // 새로운 위치로 이동 const newCoord = new window.vw.CoordZ(126.977, 37.571, 1000); map.setPosition(newCoord); } }; return ( <div> <VWorldMap ref={mapRef} config={{ apiKey: "YOUR_VWORLD_API_KEY" }} width="100%" height="500px" onMapReady={(map) => { console.log("사용 가능한 메서드:", Object.getOwnPropertyNames(map)); }} /> <button onClick={controlMap}>맵 제어</button> </div> ); } ``` ## 🔑 API 키 발급 VWorld API 키는 [VWorld 개발자 포털](https://www.vworld.kr/dev/v4dv_opnkeyinfo_s001.do)에서 발급받을 수 있습니다. ## 📚 Props ### VWorldMapProps | Prop | Type | Required | Default | Description | | -------------------- | ---------------------------------------- | -------- | --------- | ----------------- | | `config` | `VWorldConfig` | ✅ | - | VWorld API 설정 | | `options` | `Partial<VWorldMapOptions>` | ❌ | `{}` | 맵 옵션 | | `initCameraPosition` | `VWorldCameraPosition` | ❌ | 광화문 | 초기 카메라 위치 | | `cameraPosition` | `VWorldCameraPosition` | ❌ | - | 동적 카메라 위치 | | `zoom` | `number` | ❌ | - | 줌 레벨 | | `onMapReady` | `(map: VWorldMapInstance) => void` | ❌ | - | 맵 준비 완료 콜백 | | `onMapLoad` | `() => void` | ❌ | - | 맵 로드 완료 콜백 | | `onCameraChange` | `(camera: VWorldCameraPosition) => void` | ❌ | - | 카메라 변경 콜백 | | `onZoomChange` | `(zoom: number) => void` | ❌ | - | 줌 변경 콜백 | | `onMapClick` | `(coord: VWorldCoord) => void` | ❌ | - | 맵 클릭 콜백 | | `onMapDoubleClick` | `(coord: VWorldCoord) => void` | ❌ | - | 맵 더블클릭 콜백 | | `onMouseMove` | `(coord: VWorldCoord) => void` | ❌ | - | 마우스 이동 콜백 | | `onWheel` | `(delta: number) => void` | ❌ | - | 휠 스크롤 콜백 | | `onError` | `(error: string) => void` | ❌ | - | 오류 발생 콜백 | | `className` | `string` | ❌ | `''` | CSS 클래스명 | | `style` | `React.CSSProperties` | ❌ | `{}` | 인라인 스타일 | | `width` | `string \| number` | ❌ | `'100%'` | 컨테이너 너비 | | `height` | `string \| number` | ❌ | `'600px'` | 컨테이너 높이 | ### VWorldConfig | Property | Type | Required | Description | | -------- | -------- | -------- | ------------- | | `apiKey` | `string` | ✅ | VWorld API 키 | ### VWorldMapOptions | Property | Type | Default | Description | | -------------------- | --------- | ----------- | --------------------------- | | `mapId` | `string` | `'vmap'` | 맵 컨테이너 ID | | `logo` | `boolean` | `true` | 로고 표시 여부 | | `navigation` | `boolean` | `true` | 네비게이션 컨트롤 표시 여부 | | `autoRotate` | `boolean` | `false` | 자동 회전 여부 | | `showGrid` | `boolean` | `false` | 그리드 표시 여부 | | `showAxis` | `boolean` | `false` | 축 표시 여부 | | `backgroundColor` | `string` | `'#000000'` | 배경색 | | `terrain` | `boolean` | `true` | 지형 표시 여부 | | `buildings` | `boolean` | `true` | 건물 표시 여부 | | `roads` | `boolean` | `true` | 도로 표시 여부 | | `water` | `boolean` | `true` | 물 표시 여부 | | `vegetation` | `boolean` | `true` | 식생 표시 여부 | | `enableAntialiasing` | `boolean` | `true` | 안티앨리어싱 활성화 | | `enableShadows` | `boolean` | `true` | 그림자 활성화 | | `maxFPS` | `number` | `60` | 최대 FPS | ## 🛠️ 유틸리티 함수 ### 좌표 및 위치 생성 ```tsx import { createCoord, createCoordZ, createDirection, createCameraPosition, getGwanghwamunCameraPosition, } from "vworld-react-3d"; // 2D 좌표 생성 const coord2D = createCoord(126.977, 37.571); // 3D 좌표 생성 (고도 포함) const coord3D = createCoordZ(126.977, 37.571, 500); // 방향 생성 (heading, pitch, roll) const direction = createDirection(0, -45, 0); // 카메라 위치 생성 const cameraPos = createCameraPosition(coord3D, direction); // 광화문 위치 (고도 기반) const gwanghwamun = getGwanghwamunCameraPosition(1000); // 1000m 고도 ``` ## 🎯 주요 기능 ### ✅ 완전한 TypeScript 지원 - 모든 타입이 정확하게 정의됨 - IntelliSense 완벽 지원 ### ✅ React 16.8+ 호환 - Hooks 기반 구현 - forwardRef 지원으로 맵 인스턴스 직접 접근 가능 ### ✅ 자동 스크립트 로딩 - jQuery 자동 로드 - VWorld 3.0 API 자동 로드 - 순차적 스크립트 로딩으로 안정성 보장 ### ✅ 64개 공식 API 메서드 지원 - 맵 초기화 및 제어 - 카메라 위치 및 방향 제어 - 줌 및 회전 제어 - 이벤트 처리 - 성능 최적화 ### ✅ 이벤트 시스템 - 맵 준비/로드 이벤트 - 카메라 변경 이벤트 - 클릭/더블클릭 이벤트 - 마우스 이동/휠 이벤트 ### ✅ 에러 처리 - 스크립트 로딩 실패 처리 - 맵 초기화 실패 처리 - 사용자 친화적 에러 메시지 ## 🌐 브라우저 지원 - Chrome 60+ - Firefox 55+ - Safari 12+ - Edge 79+ ## 📦 패키지 구조 ``` vworld-react-3d/ ├── dist/ # 빌드된 파일들 │ ├── index.esm.js # ES 모듈 │ ├── index.d.ts # TypeScript 타입 정의 │ └── index.js # CommonJS ├── src/ │ ├── VWorldMap.tsx # 메인 컴포넌트 │ ├── types.ts # TypeScript 타입 정의 │ ├── utils.ts # 유틸리티 함수 │ └── index.ts # 진입점 ├── package.json ├── rollup.config.mjs # 빌드 설정 └── README.md ``` ## 🔧 개발 ```bash # 의존성 설치 npm install # 개발 모드 (파일 감시) npm run dev # 빌드 npm run build # 타입 체크 npm run type-check # 린트 npm run lint ``` ## 📄 라이선스 MIT License ## 🤝 기여하기 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## 🐛 문제 신고 버그나 기능 요청이 있으시면 [GitHub Issues](https://github.com/kimgh06/vworld-react-3d/issues)에 등록해주세요. ## 📝 변경 이력 ### 3.0.0 - 🎯 **VWorld 3.0 API 완전 지원** (64개 메서드) - 🎮 **카메라 제어 기능** (위치, 방향, 줌) - 📡 **완전한 이벤트 시스템** (클릭, 카메라 변경, 마우스 등) - 🛠️ **유틸리티 함수** (좌표 생성, 위치 관리) - 🔧 **forwardRef 지원** (맵 인스턴스 직접 접근) - 📚 **완전한 TypeScript 타입 정의** ### 2.0.0 - 🚀 **성능 최적화** - 🔧 **빌드 시스템 개선** - 📦 **ES 모듈 지원** ### 1.0.0 - 🎉 **초기 릴리스** - 🗺️ **기본 VWorld 3D 맵 컴포넌트** - 📱 **React 16.8+ 지원**