热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

cesium等高线_Cesium几个案例介绍

前言本文为大家介绍几个Cesium的Demo,通过这几个Demo能够对如何使用Cesium有进一步的了解,并能充分理解Cesium的强大之处和新功能。其

前言

本文为大家介绍几个Cesium的Demo,通过这几个Demo能够对如何使用Cesium有进一步的了解,并能充分理解Cesium的强大之处和新功能。其他的无需多言,如果还不太了解什么是Cesium,可以参见我的另外两篇关于Cesium的博客,下面直接进入正题。

一、 监听HTML控件

在Cesium中可以很方便的监听前台HTML控件,类似C#等语言中的MVVM。

1.1 前台控件

前台控件效果如下:

代码如下:

SRTM
SLOPE
Type

首先创建一个div,js监测此div中的控件,重要的是id。

在此div中创建input,一个或多个input对应js中的一个变量,当然此多个input之间也是相互绑定的关系。如:

此二者均对应js端的srtm变量,第一个是range类型,代表一个slide控件,第二个是一个文本框,二者相互联动,只选择其中一个控件也是可以的。重要的是data-bind属性中value后的变量名称需与js中对应。

当然也可以绑定一个下拉列表框:

这里就对应了js中的两个变量:types和selectedType。前者代表所有的可选列表及其值,后者代表选择的结果。

1.2 后台

首先创建一个viewModel对象,里面包含上述创建的各个变量,如下:

var viewModel = {

srtm: 10,

slope: 5,

types: [{

name: 'type1',

values: '100'

}, {

name: 'type2',

values: '200'

}

],

selectedType: undefined

};

而后对此变量进行监控并绑定到前台的相应控件:

Cesium.knockout.track(viewModel); // 跟踪此Model

var toolbar = document.getElementById('toolbar'); // 获取前端监控div

Cesium.knockout.applyBindings(viewModel, toolbar); // 绑定监控

这样就可以监听控件的变化事件:

Cesium.knockout.getObservable(viewModel, 'srtm').subscribe(function(value) {

...

});

可以对此值进行处理比如发送到后台或者请求相应的瓦片图层等等。不过下拉列表框的情况稍微复杂点:

Cesium.knockout.getObservable(viewModel, 'selectedType').subscribe(function(options) {

var values = options.values;

...

});

其实也就是多了一步,在定义types的时候除了name变量我们还定义了values变量,此处就需要通过options.values来取出此值,其他不变。

二、 根据地形瓦片直接绘制高程、坡度及等高线

这是Cesium 1.4.0版新添加的功能,所以一定要更新到此版本。只需要正确加载地形瓦片,Cesium可以自动算出高程设色瓦片、坡度设色瓦片以及等高线。其实也不难理解,地形瓦片中包含了空三等信息,根据这些信息自然能够计算出高度图、坡度图以及等高线,先来看效果:

加载地形瓦片图层无需多言,前面已经有过介绍:

viewer.terrainProvider = new Cesium.CesiumTerrainProvider({

url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',

requestWaterMask : true,

requestVertexNormals : true

});

然后就可以开始计算高程设色瓦片和坡度设色瓦片以及等高线,当然此块涉及到的东西太多,我只能凭借我粗浅的理解简单介绍,如有错误,望批评指正:

首先来看一下生成等高线:

var contourUniforms = {};

material = Cesium.Material.fromType('ElevationContour');

contourUniforms = material.uniforms;

contourUniforms.width = 1;

contourUniforms.spacing = 500;

contourUniforms.color = Cesium.Color.RED;

很简单的几行代码,其中Cesium.Material.fromType函数定义如下:

Material.fromType = function(type, uniforms) {

if (!defined(Material._materialCache.getMaterial(type))) {

throw new DeveloperError('material with type \'' + type + '\' does not exist.');

}

var material = new Material({

fabric : {

type : type

}

});

if (defined(uniforms)) {

for (var name in uniforms) {

if (uniforms.hasOwnProperty(name)) {

material.uniforms[name] = uniforms[name];

}

}

}

return material;

};

此函数返回一个Material对象,根据ElevationContour可以知道这是一个等高线类型的材质。uniforms是glsl着色器语言中的变量,用于控制对象颜色、位置等等。所以此处可以简单理解为得到ElevationContour类型的unifrom值并将此值作用于场景。Cesium根据此uniform生成相应类型的等高线。

理解了这一点,高程设色和坡度设色也就明白了。

高程设色如下:

var shadingUniforms = {};

material = Cesium.Material.fromType('ElevationRamp');

shadingUniforms = material.uniforms;

shadingUniforms.minHeight = -414.0;

shadingUniforms.maxHeight = 8777;

坡度设色如下:

var shadingUniforms = {};

material = Cesium.Material.fromType('SlopeRamp');

shadingUniforms = material.uniforms;

二者都需要为shadingUniforms变量添加一个色表:

shadingUniforms.image = getColorRamp(selectedShading);

var elevationRamp = [0.0, 0.045, 0.1, 0.15, 0.37, 0.54, 1.0];

var slopeRamp = [0.0, 0.29, 0.5, Math.sqrt(2)/2, 0.87, 0.91, 1.0];

function getColorRamp(selectedShading) {

var ramp = document.createElement('canvas');

ramp.width = 100;

ramp.height = 1;

var ctx = ramp.getContext('2d');

var values = selectedShading === 'elevation' ? elevationRamp : slopeRamp;

var grd = ctx.createLinearGradient(0, 0, 100, 0);

grd.addColorStop(values[0], '#000000'); //black

grd.addColorStop(values[1], '#2747E0'); //blue

grd.addColorStop(values[2], '#D33B7D'); //pink

grd.addColorStop(values[3], '#D33038'); //red

grd.addColorStop(values[4], '#FF9742'); //orange

grd.addColorStop(values[5], '#ffd700'); //yellow

grd.addColorStop(values[6], '#ffffff'); //white

ctx.fillStyle = grd;

ctx.fillRect(0, 0, 100, 1);

return ramp;

}

对高程和坡度归一化后的值设置颜色。这样就可以正常显示高程设色和坡度设色。

三、 同一场景下显示两个不同的瓦片图层

不是简单的两个图层叠加,而是真实的分割整个地图,左右显示两个不同的瓦片图层。效果如下:

首先添加两个图层,第一个创建Viewer的时候设置基础图层,第二个采用layers.addImageryProvider的方式添加(当然也可以两个都采用此种方式添加),具体添加图层的方式参考前面的博客。

layer1 = layers.addImageryProvider(...);

layer2 = layers.addImageryProvider(...);

只需要设置layer1或则layer2的splitDirection属性即可:

layer2.splitDirection = Cesium.ImagerySplitDirection.LEFT;

当然还需要设置图层分割的位置:

viewer.scene.imagerySplitPosition = 0.5;

可以改变此值来改变左右图层的分割位置,0.5表示在中间。如果需要动态调整分割位置则需要加一个分割器,监听位置变化事件。整体代码如下:

前台:

#slider {

position: absolute;

left: 50%;

top: 0px;

background-color: #D3D3D3;

width: 5px;

height: 100%;

z-index: 9999;

}

#slider:hover {

cursor: ew-resize;

}

后台:

var viewer = new Cesium.Viewer('cesiumContainer', {

baseLayerPicker: false,

imageryProvider: new Cesium.ArcGisMapServerImageryProvider({

url : 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'

})

});

var layers = viewer.imageryLayers;

var balckMarble = layers.addImageryProvider(Cesium.createTileMapServiceImageryProvider({

url : 'https://cesiumjs.org/blackmarble',

credit : 'Black Marble imagery courtesy NASA Earth Observatory',

flipXY : true

}));

balckMarble.splitDirection = Cesium.ImagerySplitDirection.LEFT;

var slider = document.getElementById('slider');

viewer.scene.imagerySplitPosition = (slider.offsetLeft) / slider.parentElement.offsetWidth;

var handler = new Cesium.ScreenSpaceEventHandler(slider);

var moveActive = false;

function move(movement) {

if(!moveActive) {

return;

}

var relativeOffset = movement.endPosition.x ;

var splitPosition = (slider.offsetLeft + relativeOffset) / slider.parentElement.offsetWidth;

slider.style.left = 100.0 * splitPosition + '%';

viewer.scene.imagerySplitPosition = splitPosition;

}

handler.setInputAction(function() {

moveActive = true;

}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

handler.setInputAction(function() {

moveActive = true;

}, Cesium.ScreenSpaceEventType.PINCH_START);

handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);

handler.setInputAction(function() {

moveActive = false;

}, Cesium.ScreenSpaceEventType.LEFT_UP);

handler.setInputAction(function() {

moveActive = false;

}, Cesium.ScreenSpaceEventType.PINCH_END);

四、 改造geocoder控件

Cesium自带了geocoder控件,可以检索并定位到某个地址,原理很简单,就是后台解析此地址,根据解析结果将地图切换到该位置。Cesium默认采用的是微软Bing地址解析引擎,如果我们想要换成其他的如OSM或者我们自己的,只需要对此控件简单改造即可。示例代码如下:

/**

* This class is an example of a custom geocoder. It provides geocoding through the OpenStreetMap Nominatim service.

* @alias OpenStreetMapNominatimGeocoder

* @constructor

*/

function OpenStreetMapNominatimGeocoder() {

}

/**

* The function called to geocode using this geocoder service.

*

* @param {String} input The query to be sent to the geocoder service

* @returns {Promise}

*/

OpenStreetMapNominatimGeocoder.prototype.geocode = function (input) {

var endpoint = 'https://nominatim.openstreetmap.org/search?';

var query = 'format=json&q=' + input;

var requestString = endpoint + query;

return Cesium.loadJson(requestString) //请求url获取json数据

.then(function (results) {

var bboxDegrees;

return results.map(function (resultObject) {

bboxDegrees = resultObject.boundingbox;

return {

displayName: resultObject.display_name,

destination: Cesium.Rectangle.fromDegrees(

bboxDegrees[2],

bboxDegrees[0],

bboxDegrees[3],

bboxDegrees[1]

)

};

});

});

};

var viewer = new Cesium.Viewer('cesiumContainer', {

geocoder: new OpenStreetMapNominatimGeocoder()

});

首先创建了一个OpenStreetMapNominatimGeocoder类,并为其添加了geocode方法,在此方法中根据输入拼接请求url,解析结果取出经纬度、名称等内容。这样就实现了我们自己的地名解析器,其实这就是C#等语言中的父类和继承的关系。

五、 总结

本文介绍了几个Cesium的案例,都是一些比较有意思和好玩的功能,后续如果搜集到其他好玩的使用案例,同样也会总结放出。



推荐阅读
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • JavaWeb中读取文件资源的路径问题及解决方法
    在JavaWeb开发中,读取文件资源的路径是一个常见的问题。本文介绍了使用绝对路径和相对路径两种方法来解决这个问题,并给出了相应的代码示例。同时,还讨论了使用绝对路径的优缺点,以及如何正确使用相对路径来读取文件。通过本文的学习,读者可以掌握在JavaWeb中正确找到和读取文件资源的方法。 ... [详细]
  • Servlet多用户登录时HttpSession会话信息覆盖问题的解决方案
    本文讨论了在Servlet多用户登录时可能出现的HttpSession会话信息覆盖问题,并提供了解决方案。通过分析JSESSIONID的作用机制和编码方式,我们可以得出每个HttpSession对象都是通过客户端发送的唯一JSESSIONID来识别的,因此无需担心会话信息被覆盖的问题。需要注意的是,本文讨论的是多个客户端级别上的多用户登录,而非同一个浏览器级别上的多用户登录。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法
    本文介绍了解决nginx启动报错epoll_wait() reported that client prematurely closed connection的方法,包括检查location配置是否正确、pass_proxy是否需要加“/”等。同时,还介绍了修改nginx的error.log日志级别为debug,以便查看详细日志信息。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • Highcharts翻译系列之二十:曲线图例子(二)
    Highcharts翻译系列之二十:曲线图例子(二)代码 ... [详细]
author-avatar
默默-的米线_601
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有