等值线/面生成一站式封装

选择要生成的点

  • 前台页面
<a-modaltitle="设置":width="900":visible="AnalysisVisible"@ok="AnalysishandleSubmit"@cancel="AnalysishandleCancel"><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">年份:</span><el-select v-model="Analysis.year" placeholder="请选择"><el-option v-for="item in AnalysisYear" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">月份:</span><el-select v-model="Analysis.month" placeholder="请选择"><el-option v-for="item in AnalysisMonth" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">等值面颜色设定:</span><color-select :color-list="colorList" v-model="settings.color"></color-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">间隔设定:</span><el-select v-model="settings.interval" placeholder="请选择"><el-option v-for="item in intervaloptions" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">生成类型:</span><el-button-group><el-button :type="type1" @click="typeSele('isobands')">等值面</el-button><el-button :type="type2" @click="typeSele('isolines')">等值线 </el-button></el-button-group></div></a-modal>
  • 给后台一个数组,返回的数据格式options如下
{color: "rgba(218,165,32,1)",extent: (4)[115.63528641258763, 38.69892119142736, 116.3275678594995, 39.17138063219472],interval: 1,type: "isobands",x: (17)[116.13, 116.09, 116.17],y: (17)[39.14, 39.09, 39.02],z: (17)[24.6, 24.5, 24.3],}

传递给mapgis插件(自封装),通过openlayers代码生成等值线

  • 封装类
/**功能:   等值线 等值面 参数: 作者:Moke邮箱:zjmoke1026@163.com时间:2021年07月23日 14:22:01版本:v1.0修改记录:修改内容:修改时间:2021年07月23日 14:22:01*/
var self;
import geojsonObject from '../../../../public/loading/xa2000.json'
export default class EquivaTool {constructor(map) {self = thisthis.map = mapthis.WFSVectorSource = nullthis.WFSVectorLayer = nullthis.vectorLayer = nullthis.vectorSource = nullthis.select = new ol.interaction.Select()this.dragBox = new ol.interaction.DragBox({condition: ol.events.condition.platformModifierKeyOnly,})}/******* * @description: * @param {*} options  前台给的配置项* @return {*}*///    等值线isolines  or  等值面isobandsCreateIsolines(options, cb) {// 传递过来的z 的最大最小值var min = Math.floor(Math.min.apply(null, options.z) - 2)var max = Math.ceil(Math.max.apply(null, options.z) + 5)// 根据z值范围调整  var breaks = []// 对值进行处理for (let i = 0, j = min; j < max; i++) {breaks.push(j)j += options.interval}//  isolines --线 isobands--面let params = {mapCenter: [116.14, 39.11],maxValue: 100,krigingModel: 'spherical', //model还可选'gaussian','spherical',exponentialkrigingSigma2: 0,krigingAlpha: 100,canvasAlpha: 0.75, //canvas图层透明度colors: [],}// 传递过来的颜色的处理var blue = []var green = []var red = []var golden = []var yellowish = []let str = ""switch (options.color) {// 金色case 'rgba(218,165,32,1)':for (let i = 0, j = 50; j < 100; i++) {j += 50 / breaks.lengthstr = `rgba(218,165,32,${(j / 100).toFixed(2)})`golden.push(str)}params.colors = goldenbreak;// 蓝色case 'rgba(0,0,255,1)':for (let i = 0, j = 50; j < 100; i++) {j += 50 / breaks.lengthstr = `rgba(0,0,255,${(j / 100).toFixed(2)})`blue.push(str)}params.colors = bluebreak;//    绿色case 'rgba(0,128,0,1)':for (let i = 0, j = 50; j < 100; i++) {j += 50 / breaks.lengthstr = `rgba(0,128,0,${(j / 100).toFixed(2)})`green.push(str)}params.colors = greenbreak;//    红色case 'rgba(255,0,0,1)':for (let i = 0, j = 50; j < 100; i++) {j += 50 / breaks.lengthstr = `rgba(255,0,0,${(j / 100).toFixed(2)})`red.push(str)}params.colors = redbreak;//    淡黄色case 'rgba(240,230,140,1)':for (let i = 0, j = 50; j < 100; i++) {j += 50 / breaks.lengthstr = `rgba(240,230,140,${(j / 100).toFixed(2)})`yellowish.push(str)}params.colors = yellowishbreak;default:break;}// 返回给前端页面的var result = {legend: []}self.WFSVectorSource = new ol.source.Vector()self.WFSVectorLayer = new ol.layer.Vector({source: self.WFSVectorSource,})self.map.addLayer(self.WFSVectorLayer)//添加选择和框选控件,按住Ctr键,使用鼠标框选采样点self.map.addInteraction(self.select)self.map.addInteraction(self.dragBox)//设置框选事件let selectedFeatures = self.select.getFeatures()self.dragBox.on('boxend', () => {let extent = self.dragBox.getGeometry().getExtent()self.WFSVectorSource.forEachFeatureIntersectingExtent(extent, (feature) => {selectedFeatures.push(feature)})drawKriging(extent)})self.dragBox.on('boxstart', () => {selectedFeatures.clear()})//利用网格计算点集const gridFeatureCollection = function (grid, xlim, ylim) {var range = grid.zlim[1] - grid.zlim[0]var i, j, x, y, zvar n = grid.length //列数var m = grid[0].length //行数var pointArray = []for (i = 0; i < n; i++)for (j = 0; j < m; j++) {x = i * grid.width + grid.xlim[0]y = j * grid.width + grid.ylim[0]z = grid[i][j]// z = (grid[i][j] - grid.zlim[0]) / range// if (z < 0.0) z = 0.0// if (z > 1.0) z = 1.0pointArray.push(turf.point([x, y], {value: z,}))}return pointArray}//绘制kriging插值图const drawKriging = (extent) => {let values = options.z,lngs = options.x,lats = options.yif (values.length > 3) {let variogram = kriging.train(values,lngs,lats,params.krigingModel,params.krigingSigma2,params.krigingAlpha)let polygons = []polygons.push([[extent[0], extent[1]],[extent[0], extent[3]],[extent[2], extent[3]],[extent[2], extent[1]],])let grid = kriging.grid(polygons, variogram, (extent[2] - extent[0]) / 500)let dragboxExtent = extentif (self.vectorLayer !== null) {self.map.removeLayer(self.vectorLayer)}self.vectorSource = new ol.source.Vector()self.vectorLayer = new ol.layer.Vector({source: self.vectorSource,opacity: 0.9,style: function (feature) {var style = new ol.style.Style({text: new ol.style.Text({text: feature.get('value') + '',scale: 1.5,}),})// 判断是等值线  还是  等值面if (options.type == 'isobands') {let ind = breaks.indexOf(parseFloat(feature.get('value').split('-')))style.fill_ = new ol.style.Fill({color: params.colors[ind],})result.type = "等值面"result.legend.push({label: feature.get('value'),value: params.colors[ind]})} else {//等值线style.stroke_ = new ol.style.Stroke({color: '#000',})result.type = "等值线"}return style},})//使用turf渲染等值面/线let fc = gridFeatureCollection(grid, [extent[0], extent[2]], [extent[1], extent[3]])var collection = turf.featureCollection(fc)// 要生成的等值效果var isobandsif (options.type == 'isobands') {//等值线isobands = turf.isobands(collection, breaks, {zProperty: 'value',})} else {//等值面isobands = turf.isolines(collection, breaks, {zProperty: 'value',})}function sortArea(a, b) {return turf.area(b) - turf.area(a)}// -------裁剪工具类start---------let features = [];isobands.features.forEach(function (layer1) {geojsonObject.features.forEach(function (layer2) {let intersection = null;try {intersection = turf.intersect(layer1, layer2);} catch (e) {layer1 = turf.buffer(layer1, 0);intersection = turf.intersect(layer1, layer2);}if (intersection != null) {intersection.properties = layer1.properties;intersection.id = Math.random() * 100000;features.push(intersection);}});});let intersections = turf.featureCollection(features);//-------------裁剪工具类end======//按照面积对图层进行排序,规避turf的一个bugintersections.features.sort(sortArea)var polyFeatures = new ol.format.GeoJSON().readFeatures(intersections, {featureProjection: 'EPSG:4326',})self.vectorSource.addFeatures(polyFeatures)self.map.addLayer(self.vectorLayer)} else {alert('有效样点个数不足,无法插值')}}// 边界的范围let extent = options.extentself.WFSVectorSource.forEachFeatureIntersectingExtent(extent, (feature) => {selectedFeatures.push(feature)})drawKriging(extent)cb(result)//返回结果 // 返回格式/*** {legend: [{label: "24-25",value: "rgba(218,165,32,0.77)"},{label: "23-24",value: "rgba(218,165,32,0.67)"},],type: "等值面"}*/}clearIsolines() {self.map.removeInteraction(self.WFSVectorSource);self.map.removeInteraction(self.vectorSource);self.map.removeInteraction(self.dragBox);self.map.removeInteraction(self.select);self.map.removeLayer(self.vectorLayer)self.map.removeLayer(self.WFSVectorLayer)}
}

生成等值线、面的图例返回到页面上生成图例

  • html
        <div class="sample"><a-button type="primary" style="padding: 3px 20px; margin-right: 10px" @click="MapImExport">导出</a-button><a-table:row-selection="rowSelection":columns="columns":data-source="datas":rowKey="(record) => record.GCEABC":pagination="false"></a-table></div><a-modaltitle="设置":width="900":visible="AnalysisVisible"@ok="AnalysishandleSubmit"@cancel="AnalysishandleCancel"><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">年份:</span><el-select v-model="Analysis.year" placeholder="请选择"><el-option v-for="item in AnalysisYear" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">月份:</span><el-select v-model="Analysis.month" placeholder="请选择"><el-option v-for="item in AnalysisMonth" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">等值面颜色设定:</span><color-select :color-list="colorList" v-model="settings.color"></color-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">间隔设定:</span><el-select v-model="settings.interval" placeholder="请选择"><el-option v-for="item in intervaloptions" :key="item.value" :label="item.label" :value="item.value"></el-option></el-select></div><div style="margin-top: 20px"><span style="width: 120px; display: inline-block; text-align: right; margin-right: 10px">生成类型:</span><el-button-group><el-button :type="type1" @click="typeSele('isobands')">等值面</el-button><el-button :type="type2" @click="typeSele('isolines')">等值线 </el-button></el-button-group></div></a-modal>
  • js
  // 分析AnalysishandleSubmit() {this.Analysis.uniCodeList = this.selectedRowKeysif (this.Analysis.uniCodeList.length < 3) {this.$message.success('选择的井不足三个无法生成等值线')return} else {postAnslysisContour(this.Analysis).then((res) => {let obj = Object.assign(this.settings, res.data.contourData)this.$refs.map.CreateEquivalence(obj)})}this.AnalysisVisible = false},// 取消AnalysishandleCancel() {this.AnalysisVisible = false},//导出调用Mapgis.vue    MapImExport() {this.$refs.map.MapImExport()},
  • css
.sample {height: 268px;overflow: auto;
}

MapGis.vue页面通过html2canvas生成图片,然后通过blob流下载等值线图

下载npm包: npm i html2canvas@1.2.2

  • html
 <a-modal v-model="visible" title="等值线预览" @ok="handleOk"><div id="image" class="Export" style="100%"><div class="ExportImg"><div class="ExTit"><h3>2021年6月</h3><p>地下水位等值线图(单位:米)</p></div><img id="MapImage" :src="MapImg" alt="" style="width: 100%" /></div><div class="IsolineLegend"><p style="font: bold 16px/26px '微软雅黑'">图例</p><div style="display: flex"><div style="margin-right: 50px"><h4 style="margin: 10px 0">监测井图例</h4><p style="font: 12px/20px '微软雅黑'"><span class="iconfont icon-zuankong" style="color: rgb(0, 255, 0); margin-right: 10px"></span>人工监测</p><p style="font: 12px/20px '微软雅黑'"><span class="iconfont icon-zuankong" style="color: rgb(255, 0, 0); margin-right: 10px"></span>自动监测</p><p style="font: 12px/20px '微软雅黑'"><span class="iconfont icon-zuankong" style="color: rgb(152 150 150); margin-right: 10px"></span>设备离线</p></div><div><h4 style="margin: 10px 0">{{ IsolineLegend.type }}图例</h4><ul style="width: 320px; display: flex; flex-wrap: wrap" v-if="IsolineLegend.type == '等值面'"><liv-for="(item, ind) in IsolineLegend.legend":key="ind"style="font: 14px/20px '微软雅黑'; margin-right: 20px"><span:style="{background: item.value,'margin-right': '15px',width: '30px',height: '20px',display: 'inline-block',}"></span>{{ item.label }}</li></ul><p v-else><span style="margin-right: 10px; display: inline-block; width: 30px; height: 3px;color:#000">——</span>等值线</p></div></div></div></div></a-modal>
  • js
  data() {return {mapgis: {}, //地图实例MapImg: '', //生成图片的地址visible: false, //预览开关wholeExtent: [], //范围IsolineLegend: {}, //等值线需要的图例结果}},    // 生成等值线CreateEquivalence(data) {data.extent = this.wholeExtentthis.Mapgiss.QueryToolClear()this.Mapgiss.CreateEquivalence(data, (res) => {this.IsolineLegend = res})},methods: {//等值线导出MapImExport() {this.visible = truevar that = this// 地图截图this.mapgis.once('postcompose', function (event) {//获取map中的canvas,并转换为图片var canvas = event.context.canvasif (navigator.msSaveBlob) {navigator.msSaveBlob(canvas.msToBlob(), 'map.png')} else {console.log(that)that.MapImg = canvas.toDataURL('image/png')// canvas.toBlob(function (blob) {//   // saveAs(blob, 'map.png')// })}})this.mapgis.renderSync()},//保存到本地handleOk(e) {//通过html2canvas插件把整个Div生成为片  点击确定实现下载   需要后台传来导出名字html2canvas(document.getElementById('image')).then(function (canvas) {var imgUri = canvas.toDataURL('image/jpeg') // 获取生成的图片的urllet el = document.createElement('a')el.href = imgUri// 指定下载的文件名el.download = '等值导出结果.png'el.hidden = truedocument.body.appendChild(el)el.click()document.body.removeChild(el)})this.visible = false},}
  • css
.Export {width: 100%;position: relative;
}
.Export .ExportImg {border: 2px solid #999;
}
.Export .ExTit {border: 1px solid #999;width: 60%;position: absolute;background: #fff;top: 1px;left: 1px;
}
.Export .ExTit > h3 {text-align: center;padding: 5px 0;
}
.Export .ExTit > p {text-align: center;padding: 0 0 0 10px;
}
.Export .IsolineLegend {background: #fff;padding: 10px;
}

以上是本人基于openlayers封装的生成等值线或者面生成的可下载为图片的部分代码,基本逻辑已描述。
逻辑步骤:
① 选择要生成的点(点里有xyz三个值)根据里面的z来判断等值间隔
② 通过设置页设置色带,间隔值,等值线/面
③ 生成的等值面通过openlayers内置的截图工具截图出来
④ 生成的地图,图例拼接起来然后通过html2canvas插件把该div导出成图片

等值线/面生成一站式封装相关推荐

  1. Java对点、线、面生成栅格瓦片jpg,并渲染呈现

    Java对点.线.面生成栅格瓦片jpg,并渲染呈现 1. 效果图 2. 原理 2.1 面瓦片的生成 2.2 线瓦片的生成 2.3 多点瓦片的生成 3. 源码 参考 这篇博客将介绍从前端HTML页面到后 ...

  2. CAD图转成Protel封装

    CAD图转成Protel封装 在Protel中制作封装很方便,如果你手中有其它格式的尺寸图,也可以导入PROTEL制作成封装,这里介绍CAD图如何转换成PROTEL封装. 要求AUTO CAD 200 ...

  3. Revit二次开发选择模型面生成新的三维视图

    觉得自己做的一些Revit二次开发的项目经验需要找个地方保存下来,不然以后碰到类似的又得去冲浪捞人家的结晶再整合,所以从今天起开始写CSDN博客啦 选择模型面生成新的三维视图 废话不多说,直接上代码! ...

  4. 解决方法:CC2640R2F从7x7改成5x5封装,主机连接失败

    一.问题 CC2640R2F 封装从7x7改成5x5,宏定义从 CC2640R2DK_7ID 修改为 CC2640R2DK_5XD 后,使用手机蓝牙与蓝牙从机连接,连接成功后马上又断开. 二.原因 晶 ...

  5. 【计算机网络复习 数据链路层】3.2 封装成帧和透明传输

    封装成帧和透明传输 一.封装成帧 二.透明传输 一.封装成帧 封装成帧就是在一段数据的前后部分添加首部和尾部,这样就构成了一个帧.接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比 ...

  6. 计算机网络数据链路层封装,计算机网络(3.3)数据链路层- 封装成帧

    数据链路层协议有许多种,但有三个基本问题则是共同的.性能 这三个基本问题是: 一.封装成帧.二.透明传输.三.差错控制.编码 封装成帧 封装成帧 (framing) 就是在一段数据的先后分别添加首部和 ...

  7. 2.封装成帧和透明传输

    一. 成帧 封装成帧就是在一段数据的前后部分添加首部和尾部,这样就构成了一个帧.接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开始和结束. 组帧的四种方法: 字符 ...

  8. 【计算机网络】—— 封装成帧 透明传输

    目录 一.数据链路层功能概述 二.封装成帧 透明传输 组帧的四种方法 一.数据链路层功能概述 数据链路层在物理层提供服务的基础上向网络层提供服务,其最基本的服务是将源自网络层来的数据可靠地传输到相邻节 ...

  9. 计算机网络——数据链路层之封装成帧和透明传输

    参考链接 CSKAOYAN.COM 封装成帧 封装成帧就是在一段数据的前后部分添加首部和尾部,这样就构成了一个帧.接收端在收到物理层上交的比特流后,就能根据首部和尾部的标记,从收到的比特流中识别帧的开 ...

  10. 数据链路层功能概述、封装成帧与透明传输

    你一定要做自己,做自己喜欢的事,然后把自己交给命运 文章目录 本章启航思维导图 数据链路层 数据链路层基本概念 数据链路层功能概述 封装成帧 透明传输 组帧的四种方法 字符计数法 字符填充法 零比特填 ...

最新文章

  1. 002_XMLHttpRequest对象
  2. 什么是 DDos 攻击
  3. Session的模拟
  4. 使用python做最简单的爬虫
  5. 使用docker部署mysql主从复制集群
  6. python地图包_Python交互地图-folium包
  7. 170819-关于JSTL的知识点
  8. python配置文件封装_Python configparser模块封装及构造配置文件代码示例
  9. 调用css样式是不调用某个属性,CSS选择器可以引用另一个选择器属性吗?
  10. 设计模式学习02:简单工厂模式、工厂模式以及抽象工厂模式(具体)
  11. C# 线程thread
  12. Linux 之 shell 比较运算符
  13. dexposed框架Android在线热修复
  14. 线性代数学习之行列式
  15. 魔兽世界 - 宏命令
  16. JS跟APP交互——H5调用原生APP的方法
  17. 微信,该文件已过期或已被清理
  18. vue:高德地图的使用
  19. 树莓派网线连接电脑查询不到ip的解决方法
  20. 鼠标动不了(灯亮着)

热门文章

  1. linux的百度网盘客户端
  2. 查看华为huawei状态码
  3. 视频教程-Windows程序设计应用开发-C/C++
  4. vmware tools的下载与安装
  5. 卡巴斯基:2019年金融行业网络威胁趋势报告
  6. 基于Spatial-Temporal Transformer的城市交通流预测
  7. 用于交通流预测的时间多图卷积网络
  8. 基于java的大学生奖学金管理系统
  9. tkinter让用户选择文件并返回可读取文件绝对地址
  10. elementUI中upload上传组件点击上传按钮,选择文件框弹出前进行提示点击确定则继续弹框选择文件上传