加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

Cesium学习笔记-工具篇10-TileLonlatsImageryProvider经纬度网格瓦片地图服务

(2018-08-11 10:44:50)
标签:

cesium

经纬度网格

经纬度瓦片

经纬度地图服务

imageryprovider

分类: Cesium
这两天经常听到有人问cesium是否能加经纬度网格,刚好自己也需要此功能,心想cesium应该提供这个api,于是在官方demo查找。几乎看遍demo,在Imagery Layers Manipulation示例找到了两个相近接口:GridImageryProvider和TileCoordinatesImageryProvider这两个接口。
http://s11/mw690/006pZnPwzy7mK0zroD0aa&690
我们来看下这两个效果:
GridImageryProvider(显示渲染网格)
http://s7/mw690/006pZnPwzy7mK0HQfLU66&690
TileCoordinatesImageryProvider(显示瓦片等级和XY序号)
http://s15/mw690/006pZnPwzy7mK0N1rJ4de&690
两个都不是想要的接口,但TileCoordinatesImageryProvider接口似乎很接近我们的需求了,于是想着是否可以对源码稍加修改,以期达到自己需求。查看源码:
http://s13/mw690/006pZnPwzy7mK0YsbLu0c&690
发现核心代码如上图,根据当前请求的等级和XY坐标,实时绘制瓦片。那我们只需要修改显示的内容为经纬度即可。本人数学逻辑不好,愣是调试两个小时才理清逻辑,下面是修改后核心代码:
TileLonlatsImageryProvider.prototype.requestImage = function (x, y, level, request) {
    var canvas = document_createElement_x_x('canvas');
    canvas.width = 256;
    canvas.height = 256;
    var context = canvas.getContext('2d');
    var cssColor = this._color.toCssColorString();
    context.strokeStyle = cssColor;
    context.lineWidth = 2;
    context.strokeRect(1, 1, 255, 255);

    var interval = 180.0 / Math.pow(2, level);
    var lon = (x + 0.5) * interval-180;
    var lat = 90 - (y + 0.5) * interval;
    //var label = 'L-' + level + 'X-' + x + 'Y-' + y;
    var labelLevel = '';
    var labelLon = '';
    var labelLat = '';
    if (lon > 0) {
        if (lat > 0) {
            //label = 'L' + level + 'E' + lon + 'N' + lat;
            labelLevel = 'L' + level;
            labelLon = 'E' + lon;
            labelLat = 'N' + lat;
        } else {
            //label = 'L' + level + 'E' + lon + 'S' + (-lat);
            labelLevel = 'L' + level;
            labelLon = 'E' + lon;
            labelLat = 'N' + (-lat);
        }
    } else {
        if (lat > 0) {
            //label = 'L' + level + 'W' + (-lon) + 'N' + lat;
            labelLevel = 'L' + level;
            labelLon = 'E' + (-lon);
            labelLat = 'N' + lat;
        } else {
            //label = 'L' + level + 'W' + (-lon) + 'S' + (-lat);
            labelLevel = 'L' + level;
            labelLon = 'E' + (-lon);
            labelLat = 'N' + (-lat);
        }
    }
    context.textAlign = 'center';
    context.fillStyle = cssColor;
    if (level > 10) {
        context.font = 'bold 16px Arial';
        context.fillText(labelLevel, 124, 100);
        context.fillText(labelLon, 124, 124);
        context.fillText(labelLat, 124, 148);
    } else {
        context.font = 'bold 25px Arial';
        context.fillText(labelLevel, 124, 94);
        context.fillText(labelLon, 124, 124);
        context.fillText(labelLat, 124, 154);
    
    //context.textAlign = 'center';
    //context.fillStyle = 'black';//绘制阴影效果
    //context.fillText(label, 127, 127);
    //context.fillStyle = cssColor;
    //context.fillText(label, 124, 24);

    return canvas;
};
新建cesium工具类:TileLonlatsImageryProvider,调用示例代码:
 var tdtImagerLayerProvider = 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",
            layer: "tiandituImg",
            style: "default",
            format: "image/jpeg",
            tileMatrixSetID: "tiandituImg",
            show: true,
            maximumLevel: 18
        });
        var mapLonlat = new TileLonlatsImageryProvider({});
        var terrainProvider = new Cesium.CesiumTerrainProvider({
            url: './sampledata/terrain/ctb-merger/'
        });

     var viewer = new Cesium.Viewer('cesiumContainer',{
        skyBox:false,
        skyAtmosphere:false,
        imageryProvider: tdtImagerLayerProvider,
        contextOptions:{
            webgl:{
                alpha:true
            }
        },
        creditContainer: "creditContainer",
        selectionIndicator: false,
        animation: false,  
        baseLayerPicker: false, 
        geocoder: false, 
        timeline: false, 
        sceneModePicker: true, 
        navigationHelpButton: false, 
        infoBox: false,  
        fullscreenButton:true
    });

     viewer.terrainProvider = terrainProvider;
     var lat = 42.006;
     var lon = 128.055;
    //取消双击事件
 viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    //设置homebutton的位置
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE=
            Cesium.Rectangle.fromDegrees(lon - 1, lat - 1, lon+1, lat + 1);//Rectangle(west, south, east, north)
    //设置初始位置
    viewer.camera.setView( {
        destination: Cesium.Cartesian3.fromDegrees(lon, lat, 300000)
    } );

    var imageryLayers = viewer.imageryLayers;
    var mapLonlatLayer = imageryLayers.addImageryProvider(mapLonlat);//添加注记图层
    imageryLayers.raiseToTop(mapLonlatLayer);//将注记图层置顶
最终效果:
http://s14/mw690/006pZnPwzy7mK1kTw731d&690
当然,如果添加地形,自动贴地,因为它本身就是一种影像服务:


我的学习公众号也开通,感兴趣的小伙伴们可以加关注:giserYZ2SS,代码交流小伙伴在公众号发消息,我会一一回复的。

http://s14/small/006pZnPwzy7q1bYCcFvad&690


0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有