cesium 中的 KmlDataSource
KmlDataSource
简介
KmlDataSource是 Cesium 中用于解析 KML / KMZ 文件的数据源类,它实现了DataSource接口。KML(Keyhole Markup Language 2.2)是 Google Earth 常用的地理标注格式,Cesium 解析后会把每一个要素转成Entity(线、点、面、图标等),统一放到entities集合中管理。
它同时支持:
kml/ovkml:纯文本的 KML 文件;kmz/ovkmz:zip 压缩包形式的 KML,Cesium 内部会自动解压,包内的图片、图标等相对资源也能一并解析。
基本使用
加载文件(URL)
最简单的方式是直接传一个文件地址,load返回一个 Promise:
viewer.dataSources.add(Cesium.KmlDataSource.load("../../SampleData/facilities.kmz",{camera:viewer.scene.camera,canvas:viewer.scene.canvas,}));三种数据形态(重点)
load的第一个参数支持三种类型,它们的含义完全不同:
| 传入类型 | 含义 | 注意事项 |
|---|---|---|
string | URL 地址(不是文件内容) | 传字符串会被当成 URL 去请求,这是最常见报错的原因 |
Blob | 二进制文件数据 | KMZ / ovkmz 压缩包可直接传 Blob,Cesium 会自动判断 zip 并解压 |
Document | 已经解析好的 XML 文档 | 适合先用DOMParser校验完 XML 再交给 Cesium |
// 1. 字符串(URL)awaitCesium.KmlDataSource.load("/data/xxx.ovkml");// 2. Blob(KMZ / ovkmz)constblob=awaitfetch("/data/xxx.ovkmz").then((r)=>r.blob());constds=awaitCesium.KmlDataSource.load(blob,{sourceUri:"/data/xxx.ovkmz",});// 3. XML Document(ovkml)consttext=await(awaitfetch("/data/xxx.ovkml")).text();constdoc=newDOMParser().parseFromString(text,"application/xml");constds=awaitCesium.KmlDataSource.load(doc,{sourceUri:"/data/xxx.ovkml",});注意:把 KML 文本字符串直接传给
load,会被当成 URL 请求,导致加载失败甚至抛RuntimeError。
加载选项 LoadOptions
sourceUri:解析 KML 内相对路径(图片、图标等)的基准 URL;clampToGround:几何要素(线、面)是否贴地,默认false;screenOverlayContainer:屏幕叠加层(ScreenOverlay)挂载的容器;camera/canvas:KML 的 NetworkLink 等特性需要相机参数时传入viewer.scene.camera和viewer.scene.canvas。
挂载到地图
viewer.dataSources.add(ds);// 显示图层viewer.dataSources.remove(ds,false);// 移除显示,false 表示不销毁,可重新加回viewer.dataSources.contains(ds);// 判断图层是否已挂载解析结果
解析完成后,数据源上可以拿到所有要素和相关信息:
ds.entities/ds.entities.values:要素集合,每个要素是一个Entity;entity.name:Placemark 的名称(如 YL_58);entity.polyline/entity.polygon/entity.point/entity.billboard:对应的图形对象;entity.parent:<MultiGeometry>拆出来的多个 entity 共享同一个 parent(即原 Placemark),可用于把同一条线的高亮整组处理;entity.kml:KmlFeatureData,包含 author、link 等 KML 元数据。
数据源本身还提供事件:
errorEvent:解析过程中出错时触发;loadingEvent:开始/结束加载时触发;changedEvent:底层数据变化时触发;unsupportedNodeEvent:遇到不支持的 KML 节点时触发。
修改样式
Cesium 里所有样式字段都是 Property,修改时要用属性类包装:
constnow=Cesium.JulianDate.now();// 读取当前线宽constwidth=entity.polyline.width?.getValue(now);// 修改线宽和颜色entity.polyline.width=newCesium.ConstantProperty(8);entity.polyline.material=newCesium.ColorMaterialProperty(Cesium.Color.fromCssColorString("#ffd400"));// 面的填充 / 描边entity.polygon.material=newCesium.ColorMaterialProperty(Cesium.Color.fromCssColorString("#ffd400").withAlpha(0.45));entity.polygon.outline=newCesium.ConstantProperty(true);entity.polygon.outlineColor=newCesium.ConstantProperty(Cesium.Color.fromCssColorString("#ffd400"));常见问题
- 传字符串报错 / RuntimeError:字符串被当成 URL,而不是文件内容;改为传 Blob 或 Document。
- 一条长线显示成一段一段:源数据里
<MultiGeometry>把折线拆成了多段<LineString>,每段是一个 entity;可以用entity.parent分组,把同一 Placemark 的段一起高亮。 - KMZ 内的图标不显示:要把整个 KMZ Blob 交给 Cesium 解析,而不是手动解压只取
doc.kml文本,否则包内相对资源无法解析。
参考资料:
KmlDataSource
KmlDataSource
