openlayers加载天地图改变颜色,添加滤镜 cesium加载天地图,添加滤镜

目录

一、openlayers

二、cesium


一、openlayers

通过css滤镜的方式改变地图颜色。

  const layerObj = new TileLayer({
    className: 'baseLayerClass',  //重点代码!!!
    zIndex: zIndex,
    source: new WMTS({
      url: 'https://t{0-7}.tianditu.gov.cn/' + serviceName + '_c/wmts?tk=' + tk,
      crossOrigin: 'anonymous',
      tileGrid: new WMTSTileGrid({
        origin: getTopLeft(projectionExtent),
        resolutions: resolutions,
        matrixIds: ids
      }),
      format: 'tiles',
      layer: serviceName,
      matrixSet: 'c',
      style: ''
    })
  });

css样式中配置 


    //地图配色
    .baseLayerClass {
        filter: grayscale(76%) sepia(55%) invert(100%) saturate(236%);

    }

二、cesium

天地图加载完之后调用

   addTiandituLayerFilter()

如果要切换主题的话,要把之前的着色器代码保存一下,方便恢复 

// 在外部保存原始着色器代码的引用
    let originalFragShaderSources = ref([]);
    // 添加颜色滤镜  主题
    function addTiandituLayerFilter() {
        if(sideTheme.value === 'theme-dark') {
            const filterParams = {
                bInvertColor: true,     // 启用颜色反转
                bFilterColor: true,     // 启用颜色过滤
                filterColor: '#0044aa'  // 过滤颜色值
            }
            tiandituLayer.brightness = 0.6  // 亮度降低
            tiandituLayer.contrast = 1.8    // 对比度增强
            tiandituLayer.gamma = 0.3       // 伽马值调整
            tiandituLayer.hue = 1           // 色相保持
            tiandituLayer.saturation = 0    // 饱和度归零
            filterLayer(filterParams)
        } else {
            // 亮色主题:恢复原始着色器
            if(originalFragShaderSources.value.length > 0) {
                viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources = originalFragShaderSources.value
            }

        }
    }
    
    function filterLayer(options) {
        const {bInvertColor, bFilterColor, filterColor }  = options
        const color =  new Cesium.Color.fromCssColorString(filterColor);
        // 提取RGB分量并转换为0-255整数
        const filterRGB = [
            Math.round(color.red * 255),
            Math.round(color.green * 255),
            Math.round(color.blue * 255)
        ]
        let fragShader = viewer.scene.globe._surfaceShaderSet.baseFragmentShaderSource.sources

        originalFragShaderSources.value = JSON.parse(JSON.stringify(fragShader))
        for (let i = 0; i < fragShader.length; i++) {
                // 定位要修改的代码位置(饱和度计算后)
            const strS = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
            let strT = 'color = czm_saturation(color, textureSaturation);\n#endif\n'
            if (bInvertColor) {
            strT += `
                color.r = 1.0 - color.r;
                color.g = 1.0 - color.g;
                color.b = 1.0 - color.b;
            `
            }
            if (bFilterColor) {
            strT += `
                color.r = color.r * ${filterRGB[0]}.0/255.0;
                color.g = color.g * ${filterRGB[1]}.0/255.0;
                color.b = color.b * ${filterRGB[2]}.0/255.0;
            `
            }
            fragShader[i] = fragShader[i].replace(strS, strT)
        }
    }

三、openlayers天地图调色demo

以下代码可以直接复制到html文件中运行,通过滑块调整获取 filter: grayscale(76%) sepia(55%) invert(100%) saturate(236%);几个参数的值,调整好以后,直接复制到代码中使用。

<!DOCTYPE html>
<html>

<head>
    <title>天地图滤镜控制</title>
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css">
    <style>
        .map {
            width: 100%;
            height: 90vh;
        }

        .controls {
            position: absolute;
            top: 10px;
            left: 50px;
            background: rgba(255, 255, 255, 0.8);
            padding: 10px;
            border-radius: 5px;
            z-index: 1000;
        }

        .control-group {
            margin: 5px 0;
        }

        label {
            display: inline-block;
            width: 120px;
        }

        /* '  hue-rotate(180deg) saturate(1600%) brightness(180%) contrast(90%)'; */
    </style>
</head>

<body>
    <div id="map" class="map"></div>
    <div class="controls">
        <div class="control-group">
            <label>Grayscale: <span id="grayscaleValue">100</span>%</label>
            <input type="range" id="grayscale" min="0" max="100" value="100">
        </div>
        <div class="control-group">
            <label>Sepia: <span id="sepiaValue">51</span>%</label>
            <input type="range" id="sepia" min="0" max="100" value="51">
        </div>
        <div class="control-group">
            <label>Invert: <span id="invertValue">100</span>%</label>
            <input type="range" id="invert" min="0" max="100" value="100">
        </div>
        <div class="control-group">
            <label>Saturate: <span id="saturateValue">350</span>%</label>
            <input type="range" id="saturate" min="0" max="500" value="350">
        </div>

    </div>

    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
    <script>
        const tk = '你的天地图token';
        // 创建投影和分辨率配置
        const projection = ol.proj.get('EPSG:4326');
        const projectionExtent = projection.getExtent();
        const size = ol.extent.getWidth(projectionExtent) / 256;
        const resolutions = new Array(20);
        const matrixIds = new Array(20);
        // 渌口区王家洲村坐标(使用高德地图获取的坐标)
        const targetLonLat = [113.138728, 27.694423]; // WGS84坐标
        const targetCoordinate = ol.proj.fromLonLat(targetLonLat);
        for (let z = 0; z < 20; ++z) {
            resolutions[z] = size / Math.pow(2, z);
            matrixIds[z] = z;
        }

        // 创建天地图图层
        const layer = new ol.layer.Tile({
            className: 'base-layer',
            source: new ol.source.WMTS({
                url: `https://t5.tianditu.gov.cn/vec_c/wmts?tk=${tk}`,
                layer: 'vec',
                matrixSet: 'c',
                format: 'tiles',
                projection: projection,
                tileGrid: new ol.tilegrid.WMTS({
                    origin: ol.extent.getTopLeft(projectionExtent),
                    resolutions: resolutions,
                    matrixIds: matrixIds
                }),
                style: 'default',
                wrapX: true,
                crossOrigin: 'anonymous'
            })
        });


        const layer_B = new ol.layer.Tile({
            className: 'base-layer',
            source: new ol.source.WMTS({
                url: `https://t5.tianditu.gov.cn/cva_c/wmts?tk=${tk}`,
                layer: 'cva',
                matrixSet: 'c',
                format: 'tiles',
                projection: projection,
                tileGrid: new ol.tilegrid.WMTS({
                    origin: ol.extent.getTopLeft(projectionExtent),
                    resolutions: resolutions,
                    matrixIds: matrixIds
                }),
                style: 'default',
                wrapX: true,
                crossOrigin: 'anonymous'
            })
        });
        // 创建地图实例
        const map = new ol.Map({
            target: 'map',
            layers: [layer,layer_B],
            view: new ol.View({
                center: targetCoordinate,  // 初始定位到目标位置
                zoom: 14  // 调整到合适的缩放级别
            })
        });

        // 获取滤镜控制元素
        const grayscale = document.getElementById('grayscale');
        const sepia = document.getElementById('sepia');
        const invert = document.getElementById('invert');
        const saturate = document.getElementById('saturate');

        // 初始化滤镜值
        let currentFilters = {
            grayscale: 100,
            sepia: 51,
            invert: 100,
            saturate: 350,


        };

        // 更新滤镜显示
        function updateDisplay() {
            document.getElementById('grayscaleValue').textContent = currentFilters.grayscale;
            document.getElementById('sepiaValue').textContent = currentFilters.sepia;
            document.getElementById('invertValue').textContent = currentFilters.invert;
            document.getElementById('saturateValue').textContent = currentFilters.saturate;

        }

        // 应用滤镜到地图
        function applyFilters() {

            const filterStr =
                `grayscale(${currentFilters.grayscale}%) ` +
                `sepia(${currentFilters.sepia}%) ` +
                `invert(${currentFilters.invert}%) ` +
                `saturate(${currentFilters.saturate}%)`;

            console.log('filterStr',filterStr);
            
            const layerElement = document.querySelector('.base-layer');
            if (layerElement) {
                layerElement.style.filter = filterStr;
            }
        }

        // 事件监听
        grayscale.addEventListener('input', (e) => {
            currentFilters.grayscale = e.target.value;
            updateDisplay();
            applyFilters();
        });

        sepia.addEventListener('input', (e) => {
            currentFilters.sepia = e.target.value;
            updateDisplay();
            applyFilters();
        });

        invert.addEventListener('input', (e) => {
            currentFilters.invert = e.target.value;
            updateDisplay();
            applyFilters();
        });

        saturate.addEventListener('input', (e) => {
            currentFilters.saturate = e.target.value;
            updateDisplay();
            applyFilters();
        });

        // 初始化显示
        updateDisplay();
        applyFilters();
    </script>
</body>

</html>

注意:

1、这个里面需要替换为自己的token

2、天地图和ol的引用使用的都是在线地址,如果加载不出来,需要替换

3、有跨域问题,可以直接用浏览器的非安全模式打开

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值