当前位置: 首页 > news >正文

分享一个基于服务端地图服务裁剪的方法

概述

需求大致是这样的:有一个全国的土地利用数据,要根据用户权限实现从省级、市级和区级不同级别的区划的不同展示,问题是数据没有关联区划数据。针对上述这个问题,我探索出了一种将区划数据发布成一个纯色(全白样式)服务,对需要展示的区域进行筛选后和原服务进行叠加,在通过代码将白色转成透明色的实现方式。

实现思路

大致实现逻辑如下逻辑图。
image.png

实现效果

合并后未抠图

抠图后

叠加到页面后

实现代码

前端使用openlayers调用,代码如下:

<!doctype html>
<html lang="en"><head><meta charset="utf-8"><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.15.1/css/ol.css"type="text/css"><style>html,body,.map {height: 100%;width: 100%;margin: 0;padding: 0;overflow: hidden;}</style><script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.15.1/build/ol.js"></script><title>OpenLayers example</title>
</head><body><div id="map" class="map"></div><script type="text/javascript">// 创建地图var map = new ol.Map({target: 'map',layers: [// 底图new ol.layer.Tile({source: new ol.source.XYZ({url: 'https://webst0{1-4}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'})}),// 使用ImageWMS源调用后端合并的WMS服务new ol.layer.Image({source: new ol.source.ImageWMS({url: 'http://localhost:8888/wms-merged',params: {'SERVICE': 'WMS','VERSION': '1.1.1','REQUEST': 'GetMap','FORMAT': 'image/png','TRANSPARENT': 'true'},serverType: 'geoserver',crossOrigin: 'anonymous'})})],view: new ol.View({center: ol.proj.fromLonLat([104.06, 30.67]),zoom: 5})});</script>
</body></html>

后端服务使用node,实现代码如下:

const express = require('express');
const axios = require('axios');
const { createCanvas, loadImage } = require('canvas');
const path = require('path');const app = express();
const PORT = process.env.PORT || 8888;// 启用CORS
app.use((req, res, next) => {res.header('Access-Control-Allow-Origin', '*');res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');next();
});// WMS合并服务
app.get('/wms-merged', async (_, res) => {try {const {SERVICE = 'WMS',VERSION = '1.1.1',REQUEST = 'GetMap',FORMAT = 'image/png',TRANSPARENT = 'true',WIDTH,HEIGHT,SRS = 'EPSG:3857',BBOX} = req.query;if (!WIDTH || !HEIGHT || !BBOX) {return res.status(400).send('缺少必要的参数: WIDTH, HEIGHT, BBOX');}const width = parseInt(WIDTH);const height = parseInt(HEIGHT);// 创建Canvasconst canvas = createCanvas(width, height);const ctx = canvas.getContext('2d');// 基础WMS URLconst wmsBaseUrl = 'http://localhost:8086/geoserver/lzugis/wms';// 图层配置const layers = [{name: 'lzugis:base_county',params: {SERVICE,VERSION,REQUEST,FORMAT,TRANSPARENT}},{name: 'lzugis:base_city',params: {SERVICE,VERSION,REQUEST,FORMAT,TRANSPARENT,CQL_FILTER: "province <> '甘肃省'"  // 这个参数可以前端传过来}}];// 构建每个图层的URLconst buildLayerUrl = (layerConfig) => {const params = new URLSearchParams();// 添加基础参数Object.keys(layerConfig.params).forEach(key => {params.append(key, layerConfig.params[key]);});// 添加图层特定参数params.append('LAYERS', layerConfig.name);params.append('WIDTH', width.toString());params.append('HEIGHT', height.toString());params.append('SRS', SRS);params.append('BBOX', BBOX);return `${wmsBaseUrl}?${params.toString()}`;};// 加载并绘制两个图层const imageUrls = layers.map(buildLayerUrl);const images = await Promise.all(imageUrls.map(url => axios.get(url, { responseType: 'arraybuffer' }).then(response => loadImage(Buffer.from(response.data)))));// 绘制第一个图层ctx.drawImage(images[0], 0, 0, width, height);// 绘制第二个图层ctx.drawImage(images[1], 0, 0, width, height);// 处理白色透明const imageData = ctx.getImageData(0, 0, width, height);const data = imageData.data;for (let i = 0; i < data.length; i += 4) {// 检查是否为白色(RGB值都接近255)if (data[i] > 240 && data[i + 1] > 240 && data[i + 2] > 240) {// 设置为透明data[i + 3] = 0;}}ctx.putImageData(imageData, 0, 0);// 设置响应头并发送图片res.setHeader('Content-Type', 'image/png');canvas.pngStream().pipe(res);} catch (error) {console.error('WMS合并错误:', error);res.status(500).send('服务器内部错误');}
});// 静态文件服务
app.use(express.static(path.join(__dirname)));// 启动服务器
app.listen(PORT, () => {console.log(`服务器运行在 http://localhost:${PORT}`);
});
http://www.dtcms.com/a/605968.html

相关文章:

  • 嵌入式Linux系统搭建本地JavaScript运行环境
  • 网站seo优化分析登录页面html模板
  • 从 0 到 1:Vue3+Django打造现代化宠物商城系统(含AI智能顾问)
  • 支持向量机(SVM)在脑电情绪识别中的学术解析与研究进展
  • dj网站建设广州有做虚拟货币网站
  • 音视频学习(七十):SVC编码
  • 营销型网站建设 ppt百度竞价广告怎么投放
  • 基于CNN-BiLSTM的室内WiFi指纹定位方法研究
  • Java八股文-01
  • 2025年11月13日 AI快讯
  • 凡科网站建设样品图seo优化关键词是什么意思
  • 力扣3703. 移除K-平衡子字符串
  • 美团龙猫大模型LongCat-Flash总结
  • C语言反编译器 | 探索C语言反编译技术的原理与应用
  • 不用wordpress建站开网站做代发
  • EDI二次开发 - 实现个性化需求的创新
  • 【AI软件开发设计】AutoDS-Free:卖家如何用 AI 搭一套零费用的代发系统?
  • 深圳网站建设服务清单建站哪家好就要用兴田德润
  • LMDeploy Docker部署FP8量化模型的详细指南
  • 网站建设的总体目标温州网站建设风格
  • 几种web鉴权方式对比
  • 网站asp木马删除胖子马wordpress模板:q8免费版
  • Modbus03功能码读取
  • 2025.11.12 力扣每日一题
  • wordpress 架站 电子书石家庄网站推广
  • 有没有哪个网站可以做LCM模组阜宁县住房与城乡建设局网站
  • 天硕SSD自主主控技术解析:如何实现工业级宽温域下的高可靠存储
  • 牛客周赛round117--------题解1
  • 锂电池 SOC 估计技术综述:成熟算法、新颖突破与车企应用实践
  • 玄机-第八章 内存马分析-java01-nacos