# DMap3D

<p align="center">
  <b>基于 Cesium 的专业三维地理信息可视化 SDK</b>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/dmap3d"><img src="https://img.shields.io/npm/v/dmap3d.svg" alt="npm version"></a>
  <a href="https://www.npmjs.com/package/dmap3d"><img src="https://img.shields.io/npm/dm/dmap3d.svg" alt="npm downloads"></a>
  <a href="https://www.npmjs.com/package/dmap3d"><img src="https://img.shields.io/npm/l/dmap3d.svg" alt="license"></a>
</p>

DMap3D 是一个功能丰富的三维 GIS SDK，基于 [Cesium](https://cesium.com/) 构建，提供 **测量、分析、绘制、军事标绘、底图加载、地形渲染、3DTiles** 等完整的三维地理信息可视化能力。适用于数字孪生、智慧城市、应急指挥、国防军事等场景。

## 特性

- **10+ 测量工具** — 空间距离、贴地距离、水平距离、面积、贴地面积、垂直截面积、高度、角度、坡度、方位角
- **11+ 分析工具** — 通视分析、可视域分析、等高线、剖面分析、天际线、缓冲区、高程极值、坡向、坡度分析、填挖方、倾斜压平
- **4 种绘制工具** — 点、线、面、圆，支持贴地模式和数据加载
- **14 种军事标绘** — 箭头、旗标、战术区域等态势标绘符号
- **多源底图** — XYZ、WMTS、WMS、GeoJSON 等标准服务
- **地形渲染** — Cesium Ion、ArcGIS、自定义地形、多地形叠加
- **3D Tiles** — 倾斜摄影、BIM 模型、点云数据加载
- **TypeScript** — 完整的类型定义，IDE 智能提示

---

## 安装

```bash
npm install dmap3d cesium
```

或使用 yarn / pnpm：

```bash
yarn add dmap3d cesium
pnpm add dmap3d cesium
```

### CDN 引入

```html
<!-- Cesium -->
<script src="https://unpkg.com/cesium/Build/Cesium/Cesium.js"></script>
<link rel="stylesheet" href="https://unpkg.com/cesium/Build/Cesium/Widgets/widgets.css">

<!-- DMap3D -->
<script src="https://unpkg.com/dmap3d/dmap3d.umd.cjs"></script>
```

---

## 快速开始

### ESM 方式

```typescript
import { DMap3D } from 'dmap3d'
import * as Cesium from 'cesium'

const viewer = new Cesium.Viewer('cesiumContainer')

// 面积测量
const areaTool = new DMap3D.measurement.area(viewer)
areaTool.activate()

// 通视分析
const viewshedTool = new DMap3D.analysis.viewshed(viewer)
viewshedTool.activate()

// 点标绘
const pointTool = new DMap3D.drawing.point({ viewer })
pointTool.draw()
```

### UMD / CDN 方式

```html
<script>
  const viewer = new Cesium.Viewer('cesiumContainer')
  const { DMap3D } = window.DMap3D

  const tool = new DMap3D.measurement.area(viewer)
  tool.activate()
</script>
```

---

## 功能模块总览

| 模块 | 命名空间 | 工具数量 | 说明 |
|------|---------|---------|------|
| 测量工具 | `DMap3D.measurement` | 10 | 距离、面积、高度、角度、坡度、方位角 |
| 分析工具 | `DMap3D.analysis` | 11 | 可视域、等高线、剖面、天际线、缓冲区等 |
| 绘制工具 | `DMap3D.drawing` | 4 | 点、线、面、圆 |
| 军事标绘 | `DMap3D.military` | 14 | 箭头、旗标、战术区域 |
| 底图服务 | `DMap3D.basemap` | 4 | XYZ、WMTS、WMS、GeoJSON |
| 地形 | `DMap3D.terrain` | 6 | 世界地形、ArcGIS、自定义、多地形叠加 |
| 3D瓦片 | `DMap3D.tiles3d` | 1 | 倾斜摄影、BIM、点云 |

---

## 测量工具 `DMap3D.measurement`

### 通用 API

所有测量工具共享以下方法：

| 方法 | 说明 |
|------|------|
| `activate()` | 激活测量（进入交互模式） |
| `deactivate()` | 停用测量（保留结果） |
| `clear()` | 清除所有测量结果 |
| `destroy()` | 完全销毁，释放资源 |

**交互操作：** 鼠标左键添加点，右键完成测量。

### 距离测量

```typescript
// 空间直线距离（多点折线）
const tool = new DMap3D.measurement.spaceDistance(viewer)
tool.activate()
tool.onMeasureEnd((distance) => {
  console.log('总距离:', distance, '米')
})

// 水平投影距离（排除高度差）
const hTool = new DMap3D.measurement.horizontalDistance(viewer)

// 贴地距离（沿地形表面）
const sTool = new DMap3D.measurement.surfaceDistance(viewer)
```

### 面积测量

```typescript
// 投影面积（WGS84 椭球算法，自动单位换算）
const tool = new DMap3D.measurement.area(viewer, {
  colors: { line: '#FBFB00', point: '#0008FF', polygon: '#33fc05' },
  fontSize: 14,
})
tool.activate()
tool.onMeasureEnd((area) => console.log('面积:', area, '平方米'))

// 贴地表面积（考虑地形起伏）
const surfTool = new DMap3D.measurement.surfaceArea(viewer)

// 垂直截面积
const vertTool = new DMap3D.measurement.verticalArea(viewer)
```

### 高度测量

```typescript
const tool = new DMap3D.measurement.height(viewer)
tool.activate()
tool.onMeasureEnd((result) => {
  console.log('绝对高度:', result.absoluteHeight, '米')
  console.log('相对高度差:', result.relativeHeight, '米')
  console.log('水平距离:', result.horizontalDistance, '米')
})
```

### 角度测量

```typescript
// 三点夹角测量（起点 → 顶点 → 终点）
const tool = new DMap3D.measurement.angle(viewer)
tool.updateConfig({
  pointColor: '#ff0000',
  sectorColor: 'rgba(255, 255, 0, 0.3)',
  fontSize: 16,
})
tool.start()
```

### 坡度 & 方位角

```typescript
// 坡度（度数 + 百分比）
const slopeTool = new DMap3D.measurement.slope(viewer)
slopeTool.activate()

// 方位角（相对正北 0°-360°）
const azimuthTool = new DMap3D.measurement.azimuth(viewer)
azimuthTool.activate()
```

### 完整工具列表

| 工具 | 类名 | 说明 |
|------|------|------|
| `measurement.area` | Area | 投影面积测量 |
| `measurement.surfaceArea` | SurfaceArea | 贴地表面积测量 |
| `measurement.verticalArea` | VerticalArea | 垂直截面积测量 |
| `measurement.height` | Height | 高度差测量 |
| `measurement.spaceDistance` | SpaceDistance | 空间直线距离 |
| `measurement.horizontalDistance` | HorizontalDistance | 水平投影距离 |
| `measurement.surfaceDistance` | SurfaceDistance | 贴地距离 |
| `measurement.angle` | Angle | 三点夹角测量 |
| `measurement.slope` | Slope | 坡度测量 |
| `measurement.azimuth` | Azimuth | 方位角测量 |

---

## 分析工具 `DMap3D.analysis`

### 通视分析

```typescript
const tool = new DMap3D.analysis.viewshed(viewer)
tool.activate()
// 左键设置观察点 → 移动鼠标确定方向 → 再次点击完成
// 绿色线 = 可见，红色线 = 遮挡
tool.onAnalysisEnd((result) => {
  console.log('是否可见:', result.isVisible)
  if (!result.isVisible) {
    console.log('遮挡点:', result.intersectionPoint)
  }
})
```

### 可视域分析

```typescript
// 基于视锥体的区域可见性分析
const tool = new DMap3D.analysis.viewshedArea(viewer)
tool.startAnalysis()
```

### 等高线分析

```typescript
const tool = new DMap3D.analysis.contour(viewer)
tool.setSpacing(50)      // 等高距 50 米
tool.setWidth(2)         // 线宽 2px
tool.setColor('#00ff00') // 绿色

tool.show()  // 显示
tool.hide()  // 隐藏

// 动态调整（立即生效）
tool.setSpacing(100)
tool.setColor('#ff0000')
```

### 剖面分析

```typescript
const tool = new DMap3D.analysis.profile(viewer, {
  perStep: 50,
  showChart: true,
  chartPosition: { bottom: '20px', width: '600px', height: '240px' },
})
tool.activate()
// 左键添加路径点，右键完成 → 底部显示高程剖面图
```

### 天际线分析

```typescript
const tool = new DMap3D.analysis.skyline(viewer, { color: '#FF0000' })
tool.init()
const data = await tool.getSkyline2D()
```

### 缓冲区分析

```typescript
const tool = new DMap3D.analysis.bufferAnalysis(viewer, {
  bufferDistance: 100,
  geometryType: 'polygon',   // 'point' | 'polyline' | 'polygon'
  bufferColor: '#FF0000',
  bufferAlpha: 0.3,
})
tool.activate()
tool.setBufferDistance(200)   // 动态调整
tool.setGeometryType('polyline')
```

### 填挖方分析

```typescript
const tool = new DMap3D.analysis.cutFill(viewer, {
  showTriangle: true,
  showRangeBox: true,
  showBasePlane: true,
  showResultLabel: true,
})
tool.onAnalysisEnd((data) => {
  console.log('挖方量:', data.cutVolume, '立方米')
  console.log('填方量:', data.fillVolume, '立方米')
  console.log('基准高度:', data.baseHeight, '米')
})
tool.activate()
```

### 完整工具列表

| 工具 | 说明 |
|------|------|
| `analysis.viewshed` | 通视分析（两点可视性检测） |
| `analysis.viewshedArea` | 可视域分析（视锥体区域分析） |
| `analysis.contour` | 等高线分析 |
| `analysis.profile` | 剖面分析（高程剖面图） |
| `analysis.skyline` | 天际线分析 |
| `analysis.bufferAnalysis` | 缓冲区分析 |
| `analysis.elevationExtremum` | 区域高程极值分析 |
| `analysis.aspectAnalyse` | 坡向分析 |
| `analysis.slopAnalyse` | 坡度分析 |
| `analysis.cutFill` | 填挖方分析（土方量计算） |
| `analysis.flattenAnalysis` | 倾斜摄影压平 |

---

## 绘制工具 `DMap3D.drawing`

### 点标绘

```typescript
const tool = new DMap3D.drawing.point({
  viewer,
  style: {
    radius: 10,
    fillColor: '#FF0000',
    strokeColor: '#FFFFFF',
    width: 2,
  },
  autoDestroy: false,  // false = 连续绘制
})

// 交互绘制
tool.draw((entity, position) => {
  console.log('绘制了一个点')
})

// 从数据加载
tool.loadFromData([[116.4, 39.9, 0], [116.5, 40.0, 100]])

// 动态修改样式（已有点立即更新）
tool.setStyle({ radius: 15, fillColor: '#00FF00' })
```

### 线标绘

```typescript
const tool = new DMap3D.drawing.polyline({
  viewer,
  style: { width: 3, color: '#FF0000', alpha: 1.0 },
  clampToGround: true,   // 贴地
})

tool.draw((entity, positions) => {
  console.log('顶点数:', positions.length)
})

// 从经纬度数组加载
tool.loadFromData([[116.39, 39.90], [116.40, 39.91], [116.41, 39.90]])
```

### 面标绘

```typescript
const tool = new DMap3D.drawing.polygon({
  viewer,
  style: {
    fillColor: '#0000FF',
    fillAlpha: 0.3,
    outlineColor: '#FFFFFF',
    outlineWidth: 2,
  },
  clampToGround: true,
})

tool.draw((entity, positions) => {
  console.log('多边形完成')
})
```

### 圆标绘

```typescript
const tool = new DMap3D.drawing.circle({
  viewer,
  style: { fillColor: '#33fc05', fillAlpha: 0.3, outlineColor: '#FBFB00' },
  clampToGround: true,
})
tool.draw((entity, center, radius) => {
  console.log('半径:', radius, '米')
})
```

---

## 军事标绘 `DMap3D.military`

专业态势标绘工具，用于军事/应急场景。

### 箭头类

| 工具 | 说明 |
|------|------|
| `military.FineArrow` | 细箭头 |
| `military.StraightArrow` | 直箭头 |
| `military.AssaultDirection` | 突击方向 |
| `military.AttackArrow` | 进攻箭头 |
| `military.DoubleArrow` | 双箭头 |
| `military.TailedAttackArrow` | 燕尾进攻箭头 |
| `military.SquadCombat` | 分队战斗 |
| `military.TailedSquadCombat` | 燕尾分队战斗 |

### 旗标类

| 工具 | 说明 |
|------|------|
| `military.CurveFlag` | 曲线旗标 |
| `military.RectFlag` | 矩形旗标 |
| `military.TriangleFlag` | 三角旗标 |

### 区域类

| 工具 | 说明 |
|------|------|
| `military.Lune` | 弓形区域 |
| `military.ClosedCurve` | 封闭曲线 |
| `military.GatheringPlace` | 聚集地 |

---

## 底图服务 `DMap3D.basemap`

```typescript
// XYZ 瓦片（OpenStreetMap、天地图等）
const xyz = new DMap3D.basemap.XYZLayer({
  url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
  credit: 'OpenStreetMap',
})

// WMTS 标准服务
const wmts = new DMap3D.basemap.WMTSLayer({ /* ... */ })

// WMS 标准服务
const wms = new DMap3D.basemap.WMSLayer({ /* ... */ })

// GeoJSON 矢量数据
const geojson = new DMap3D.basemap.GeoJsonLayer({ /* ... */ })
```

---

## 地形 `DMap3D.terrain`

```typescript
// Cesium Ion 世界地形（推荐）
const terrain = new DMap3D.terrain.WorldTerrainLayer({
  requestWaterMask: true,
  requestVertexNormals: true,
})
viewer.terrainProvider = await terrain.getTerrainProviderAsync()

// ArcGIS 地形
const arcgis = new DMap3D.terrain.ArcGisTerrainLayer({ url: '...' })

// 自定义地形服务
const custom = new DMap3D.terrain.CesiumTerrainLayer({ url: '...' })

// 无地形（椭球体）
const flat = new DMap3D.terrain.EllipsoidTerrainLayer()
viewer.terrainProvider = flat.getTerrainProvider()
```

---

## 3D Tiles `DMap3D.tiles3d`

```typescript
const tiles = new DMap3D.tiles3d.Tiles3DLayer(viewer)
tiles.load('/path/to/tileset.json')
```

---

## 环境要求

- **Cesium** >= 1.112.0（必需）
- **Three.js** >= 0.180.0（可选，3D 编辑器）
- **React** >= 18.0（可选，React 集成）

## 浏览器兼容

- Chrome >= 90
- Firefox >= 90
- Edge >= 90
- Safari >= 15

## 文档

- [在线文档](https://www.dmap3d.cn/docs/)
- [示例库](https://www.dmap3d.cn/docs/examples/intro)
- [API 参考](https://www.dmap3d.cn/docs/api/intro)
## License

MIT - DMap3D Team
