最近因为导师项目准备使用cesium,故开坑cesium,本文主要是记录cesium框架部署使用的思路以及遇到的问题。
今天开坑学习cesium~
首先要安装node.js,可参见添加链接描述
安装http-server,可参见http-server的安装和使用
笔者是遇到了一个问题,显示http-server不是外部也不是内部命令,这时先去其安装路径下找到http-server.md的目录,我的是D:\program\node_cache,然后通过命令行进入存放html的文件夹,输入如下,得到结果也如下图。
在浏览器地址栏输入http://192.168.169.1:8080/index.html回车运行即可。
小示例
<head>
<title>Cesium</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
<script src="./Cesium/Cesium.js"></script>
<link rel="stylesheet" href="./Cesium\Widgets/widgets.css">
<style></style>
</head>
<body>
<div id="cesiumContainer" style="width:600px;height:400px"></div>
<script>
var viewer =new Cesium.Viewer('cesiumContainer');
</script>
new Cesium.Viewer表示新开一个3D视窗。可在script中添加如下代码去除水印。
viewer._cesiumWidget._creditContainer.style.display="none";
Viewer中可设置是否显示时间线,各种控件是否开启等等,具体可参考API文档中关于Viewer介绍的部分。
在控件中添加天地图
这个倒是浪费了我几个小时时间,老是显示我密钥不正确,烦~
这里我是把代码添加在Censium.js里,添加在在原本的function createDefaultImageryProviderViewModels() {里面。密钥自己去官网申请,很方便。
function createDefaultImageryProviderViewModels() {
var providerViewModels = [];
var tian_Imagery =new Cesium.WebMapTileServiceImageryProvider({
url: "http://t0.tianditu.com/img_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=申请的密钥",
layer: "tdtBasicLayer",
style: "default",
format: "image/jpeg",
tileMatrixSetID: "GoogleMapsCompatible",
show: false
});
providerViewModels.push(new ProviderViewModel({
name : '天地图影像',
iconUrl : buildModuleUrl('Widgets/Images/ImageryProviders/bingAerial.png'),
tooltip : '天地图影像'+"\n"+'http://lbs.tianditu.gov.cn/',
creationFunction : function() {
return tian_Imagery;
}
}));
加载geojson格式数据以及管理其图层
添加图层
var geojsonOptions = { //防止高程遮挡(GeoJsonDataSource.load参数)
clampToGround: true
}
var promise =Cesium.GeoJsonDataSource.load('./data/base/pool.json',geojsonOptions);
promise.then(function(dataSource) {
var entities = dataSource.entities.values;
var Coloroption=Cesium.Color.DODGERBLUE;
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
entity.polygon.extrudedHeight = 1;
entity.polygon.material =Coloroption;
}
});
viewer.dataSources.add(promise);
viewer.flyTo(promise);
flyTo函数指视野移动到加载的数据位置,这里有一个for循环,我是给里面所有矢量要素(我这里是面要素)添加单位1 的高度防止被3D视图下的地形遮挡。
删除图层
图层加载进来后名字就是原来的‘XXXX.json’,只需要查找起名字对应的数据的序号,根据序号删除即可。我这里是设置图层删除按钮的id值和图层名字对应,这样可实现根据按钮id值找到对应图层删除即可。
for (var i = 0; i < viewer.dataSources.length; i++) { //删除图层
if (viewer.dataSources.get(i).name.indexOf($(this).attr('id') + ".json") != -1) {
viewer.dataSources.remove(viewer.dataSources.get(i));
i--;
}
遇到的问题
在加载geojson中我遇到了一个问题,就是当geojson包含的矢量要素过多,浏览器便会崩溃,这个时候可用矢量瓦片来代替geojson,但是同时失去了点击矢量显示属性的效果,这个时候可以利用后端获取点击屏幕的位置对相应图层分析得到属性返回前端显示即可,当然这就是后话了。
加载geoserver发布的WMTS数据(矢量瓦片)
关于geoserver的安装以及发布wmts,网上一大堆教程再次不表。发布数据的流程也就是工作区间确定、数据存储中加载shp数据,设置Gridset(切片策略)这里我用的是自带的EPSG:4326,图层发布(我shp的数据坐标系是EPSG:3857,但是却老是出错,无奈在发布页面将定义投影改成了EPSG:4326),切片(切片可以自己设置瓦片的存储路径,这个需要修改geoserver里的相关设置,网上发布wmts里的教程会有),这里我说一下加载方法:
添加图层
var wgs84=new Cesium.GeographicTilingScheme();
var wmtsImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
url : 'http://localhost:8080/geoserver/gwc/service/wmts/rest/cite:dry/{style}/{TileMatrixSet}/{TileMatrixSet}:{TileMatrix}/{TileRow}/{TileCol}?format=image/png',
layer : 'cite:dry2',
style : 'polygon',
format : 'image/png',
tileMatrixSetID:'EPSG:4326',
tilingScheme:wgs84//一般使用EPSG:3857坐标系
});
eval(id+"=viewer.imageryLayers.addImageryProvider(wmtsImageryProvider)"); //将单独图层放进列表
因为我是面数据所以style格式是polygon,这里我用的是eval()动态命名,为什么这样做呢,因为我觉得这样做删除图层比较方便。注意:这里我加了TilingScheme相关语句是因为我用的数据是EPSG:4326坐标系,所以要加上它防止瓦片位置不对。
遇到的问题(跨域问题)
因为你用geoserver发布的数据端口和网站端口不一致,所以当你加载图层时,加载不出来,查看控制台报错时发现报跨域错误,这时可参考Geoserver 安装及CORS跨域资源访问配置
删除图层
怎么动态加怎么动态删,这里是imageryLayers对象,和之前geojson的删除方法不一样。
eval("viewer.imageryLayers.remove("+$(this).attr('id')+")");
加载geoserver发布的WMS数据(栅格瓦片)
关于geoserver如何发布WMS数据略去不表。
var provider = new Cesium.WebMapServiceImageryProvider({
url: 'http://localhost:8090/geoserver/cite/wms',
layers: 'cite:pop',
parameters: {
service : 'WMS',
format: 'image/png',
transparent: true,
}
eval(id+"=viewer.imageryLayers.addImageryProvider(provider)");
删除图层方法和上面那个一样。
遇到的问题
现在遇到的问题主要是geoserver上矢量瓦片发布的样式和栅格数据发表的样式(如背景值透明等等),这些笔者将在下一篇深入探讨!!