像素个性化
更新时间:2022年6月6日
简介
为满足图像、图像瓦片类数据的前端个性化展示需求,JSAPI增加图像覆盖物的像素个性化以及基于三方标准图层的像素个性化支持;MapVGL增加PixelLayer图层可实现数据的高度显示,数据源除支持图像数据,还支持ArrayBuffer形式传入float类型的单波段数据。
像素个性化支持用户可根据来源图像的rgba波段运算,输出目标像素计算值;用户可以设置目标像素计算值相对应的颜色带(渐变带/块带);用户可以设置目标像素计算值显示区间,用于数据过滤;支持基于图像的掩膜设置;支持用户基于鼠标交互事件,输出来源图像像素以及目标像素计算值。
像素个性化支持用户可根据来源图像的rgba波段运算,输出目标像素计算值;用户可以设置目标像素计算值相对应的颜色带(渐变带/块带);用户可以设置目标像素计算值显示区间,用于数据过滤;支持基于图像的掩膜设置;支持用户基于鼠标交互事件,输出来源图像像素以及目标像素计算值。
类参考
1.BMapGL.GroundOverlay地面叠加层的图像覆盖物【type: 'image'】
在构造函数参数GroundOverlayOptions中新增以下参数
参数名称 | 二级参数名称 | 类型 | 描述 |
isPixelMap | bool | 是否启用像素模式,默认false | |
pixelMap | object | 具体像素参数 | |
fomularC | string | 像素映射value值公式,需要符合C语法。默认使用r波数据。` float generateValue(vec4 pixel){ return pixel.r * 255.; } ` | |
fomularJS | function | 像素映射value值公式,需要符合JS语法。默认使用r波数据。 function (pixel) { return pixel.r; } | |
domain | array[2] | 设置value范围,索引0的值为最小value,索引1的值为最大value。默认[0, 255] | |
clamp | array[2] | 显示区域,如果不设置,则使用domain。 | |
colors | array | 颜色带对应的颜色,默认['#F9F871', '#FFC75F', '#FF9671', '#FF6F91', '#D65DB1', '#845EC2'] | |
positions | array | 颜色对应的位置,如果positions与colors长度一致,代表是渐变色;如果positions比colors长度大1,代表是色块。由于是使用数值区间的比例来进行颜色划分,所以可以使用[0-1]来划分,也可以使用domain区间数据来划分,或者其他数值区间。默认[0, 0.2, 0.4, 0.6, 0.8, 1] | |
noData | number | 无效值,如果计算像素值等于noData则不显示。默认是-99999。 | |
maskPng | string | 掩膜图像。根据透明度设置图像的透明度。 | |
maskCoord | array[Point,Point] | 掩膜图像的百度经纬度坐标。如果不设置,则使用图像自身的四至坐标。第一个Point为左下角坐标,第二个坐标为右上角坐标。 | |
maskData | number | 根据掩膜图像的r波段的像素值进行掩膜。默认不开启。 |
GroundOverlay新增方法
方法名 | 参数 | 返回值 | 说明 |
setIsPixelMap | bool | 无 | 设置是否启用像素模式 |
setFomular | (string,function) | 无 | 第一个参数需要满足c语法,第二个参数需要满足JS语法。 参数输入都为rgba的对象,但是第一个参数的rgba每个值范围为[0-1.0],第二个参数的rgba每个参数的取值范围为[0,255]。 第一个参数可修改红色部分,绿色部分需要保留。 `float generateValue(vec4 pixel){ return (pixel.r+pixel.g+pixel.b)/3. * 255.; }` |
setDomain | array[2] | 无 | 设置value范围 |
setClamp | array[2] | 无 | 设置显示的最小值与最大值 |
setColors | array | 无 | 设置颜色值 |
setPositions | array | 无 | 设置颜色值对应的位置 |
getImagePixel | Point | [r,g,b,a] | 输入点坐标为mc坐标,输出为源图像的像素点数据。 |
getValue | array[r,g,b,a] | float/null | 输入数组为像素值,输入值是通过fomularJS函数进行计算得到,且需要满足clamp的范围,否则返回null |
setNoData | number | 无 | 设置无效值 |
setMaskPng | string | 无 | 设置掩膜图像 |
setMaskCoord | array[Point,Point] | 无 | 设置掩膜图像地理位置 |
setMaskData | number | 无 | 设置掩膜图像r波段数值 |
GroundOverlay事件新增返回内容
事件名 | 新增内容 | 说明 |
onclick | ||
color | 输入图像的像素值 | |
value | 根据fomularJS计算的值 |
onmousemove可以通过getImagePixel/getValue方法获取数据
2.基于BMapGL.XYZLayer三方标准图层的新对象BMapGL.PixelLayer
构造函数:
构造函数 | 描述 |
BMapGL.PixelLayer(options) | PixelLayer实例化XYZLayer,用于添加第三方标准图层,通过options可以设置XYZLayer之外,还需要设置像素可视化相关的配置options内容。 |
基于BMapGL.XYZLayer构造函数的options变量增加以下:
参数名称 | 二级参数名称 | 类型 | 描述 |
layer | XYZLayer对象 | 根据输入的options实例化BMapGL.XYZLayer | |
pixelMap | object | 具体像素参数 | |
opacity | float | 透明度,取值范围[0-1]。如果数值小于1,则XYZ图层的useThumbData参数会是false。 | |
fomularC | string | 像素映射value值公式,需要符合C语法。默认使用r波数据。 ` float generateValue(vec4 pixel){ return pixel.r * 255.; } ` | |
fomularJS | function | 像素映射value值公式,需要符合JS语法。默认使用r波数据。 function (pixel) { return pixel.r; } | |
domain | array[2] | 设置value范围,索引0的值为最小value,索引1的值为最大value。默认[0, 255] | |
clamp | array[2] | 显示区域,如果不设置,则使用domain。 | |
colors | array | 颜色带对应的颜色,默认['#F9F871', '#FFC75F', '#FF9671', '#FF6F91', '#D65DB1', '#845EC2'] | |
positions | array | 颜色对应的位置,如果positions与colors长度一致,代表是渐变色;如果positions比colors长度大1,代表是色块。由于是使用数值区间的比例来进行颜色划分,所以可以使用[0-1]来划分,也可以使用domain区间数据来划分,或者其他数值区间。默认[0, 0.2, 0.4, 0.6, 0.8, 1] | |
noData | number | 无效值,如果计算像素值等于noData则不显示。默认是-99999。 | |
maskPng | string | 掩膜图像。根据透明度设置图像的透明度。 | |
maskCoord | array[Point,Point] | 掩膜图像的百度经纬度坐标。如果不设置,则使用图像自身的四至坐标。第一个Point为左下角坐标,第二个坐标为右上角坐标。 | |
maskData | number | 根据掩膜图像的r波段的像素值进行掩膜。默认不开启。 |
新增方法
方法名 | 参数 | 返回值 | 说明 |
setOpacity | float | 无 | 设置透明度,如果小于1需要提前将XYZ图层的useThumbData参数设置为false。 |
setIsPixelMap | bool | 无 | 设置是否启用像素模式 |
setFomular | (string,function) | 无 | 第一个参数需要满足c语法,第二个参数需要满足JS语法。参数输入都为rgba的对象,但是第一个参数的rgba每个值范围为[0-1.0],第二个参数的rgba每个参数的取值范围为[0,255]。第一个参数可修改红色部分,绿色部分需要保留。 `float generateValue(vec4 pixel){ return (pixel.r+pixel.g+pixel.b)/3. * 255.; }` |
setDomain | array[2] | 无 | 设置value范围 |
setClamp | array | 无 | 设置显示的最小值与最大值 |
setColors | array | 无 | 设置颜色值 |
setPositions | array | 无 | 设置颜色值对应的位置 |
getImagePixel | Point | [r,g,b,a] | Point为输入点坐标为mc坐标,输出为源图像的像素点数据。 |
getValue | array[r,g,b,a] | float/null | 输入数组为像素值,输入值是通过fomularJS函数进行计算得到,且需要满足clamp的范围,否则返回null |
setNoData | number | 无 | 设置无效值 |
setMaskPng | string | 无 | 设置掩膜图像 |
setMaskCoord | array[Point,Point] | 无 | 设置掩膜图像地理位置 |
setMaskData | number | 无 | 设置掩膜图像r波段数值 |
事件
事件名 | 新增内容 | 说明 |
onclick | ||
color | 输入图像的像素值 | |
value | 根据fomularJS计算的值 |
onmousemove可以通过getImagePixel/getValue方法获取数据
3.MapVGL像素图层
mapvgl.PixelLayer
实现数据的高度显示,数据源除支持图像数据,还支持ArrayBuffer形式传入float类型的单波段数据。可根据来源图像的rgba波段运算,输出目标像素计算值;可设置目标像素计算值相对应的颜色带(渐变带/块带);可以设置目标像素计算值显示区间,用于数据过滤;支持基于几何图形的掩膜设置;支持用户基于鼠标交互事件,输出来源图像像素以及目标像素计算值。
构造方法
构造函数 | 描述 |
mapvgl.PixelLayer(options) | 实现图像像素数据的可视化展示 |
options参数除继承基础图层参数外,增加以下:
参数名称 | 二级参数名称 | 类型 | 描述 |
source | object | 图像数据源 | |
image | url | 两种数据形式,一种是ArrayBuffer,此类数据需要输入width,height两个参数。一种是图像的url,不需要输入width,height两个参数。 | |
width | int | 图像数据的宽度 | |
height | int | 图像数据的高度 | |
domain | array[2] | 颜色带对应的数据映射区间 | |
clamp | array[2] | 显示区域,如果不设置,则使用domain | |
noData | float | 非法数值 | |
isTerrain | bool | 是否采用高程显示 | |
gridRowMax | int | 采样行数,最大1600。如果图像宽度小于最大值,会使用图像宽度。 | |
gridColMax | int | 采样列数,最大1600。如果图像高德小于最大值,会使用图像高度。 | |
baseLine | float | 高度水平线,可以通过此参数可以设置基础高度映射到0,默认是0。 | |
elevationScale | float | 高程缩放因子,默认是1。 | |
refColors | 像素计算的value值采用颜色带进行渲染 | ||
colors | array | 颜色带对应的颜色,必需输入,可以参考:['#F9F871', '#FFC75F', '#FF9671', '#FF6F91', '#D65DB1', '#845EC2'] | |
positions | array | 颜色对应的位置,如果positions与colors长度一致,代表是渐变色;如果positions比colors长度大1,代表是色块。由于是使用数值区间的比例来进行颜色划分,所以可以使用[0-1]来划分,也可以使用domain区间数据来划分,或者其他数值区间。,必需输入,可以参考:[0, 0.2, 0.4, 0.6, 0.8, 1] | |
refImage | 使用图像渲染 | ||
url | string | 图像地址 | |
noTextureData | array[r,g,b] | 过滤像素,可选,默认[0,0,0] | |
fomularC | string | 像素映射value值公式,需要符合C语法。默认使用r波数据。 ` float generateValue(vec4 pixel){ return pixel.r * 255.;} ` | |
fomularJS | function | 像素映射value值公式,需要符合JS语法。默认使用r波数据。 function (pixel) { return pixel.r; } | |
linearOpacity | 像素计算值根据domain映射到0-1,对start至end之间的值进行平滑透明度 | ||
start | float | 0到start会映射到0,取值范围0-1 | |
end | float | end到1会映射到1,取值范围0-1 | |
base | float | 增加透明度,默认是0。 | |
opacity | float | 透明度,取值范围[0-1] | |
stencilData | array[geojson] | 设置掩膜区域。如果有数据,则stencilTest会是true | |
depthTest | bool | 深度测试,默认false | |
depthMask | bool | 写入深度,默认false | |
stencilAfter | bool | 后续图层是否使用掩膜数据,默认false | |
enablePicked | bool | 是否启用点击事件 | |
onClick | function | 点击事件,返回对象。dataIndex值为通过fomularJS计算值。 | |
filterColor | string | 将输入颜色与filterColor进行叠加计算,默认不进行。参数示例:'rgba(1, 255, 1, 1.0)' | |
brightness | float | 亮度。默认0,取值范围-1到1 | |
contrast | float | 对比度。默认0,取值范围-1到1 | |
exposure | float | 曝光度。默认0,取值范围-1到1 | |
saturation | float | 饱和度。默认0,取值范围-1到1 |
方法
方法名 | 参数 | 返回值 | 说明 |
setData | array[1] | 无 | 通过geojson形式,设置图像四至坐标 |
setOptions | object | 无 | 改变或设置某个参数值,通过此方法。 |
getValue | * Point 点坐标 * int 扩大范围 |
object {result, pixel, max} | 通过坐标点查找到像素,可通过扩大计算范围,根据fomularJS计算出数值,返回result代表平均值,max代表最大值,pixel是像素点[r,g,b,a]。 |
使用示例
1图像覆盖物
var map = new BMapGL.Map("container"); map.enableScrollWheelZoom(true); map.centerAndZoom(new BMapGL.Point(116.47153407391221, 40.260579778320434), 10); // 定义方法:处理参数,实例GroundOverlay function drawImage(x1, y1, x2, y2, url, opt) { var pStart = new BMapGL.Point(x1, y2); var pEnd = new BMapGL.Point(x2, y1); var bounds = new BMapGL.Bounds(new BMapGL.Point(pStart.lng, pStart.lat), new BMapGL.Point(pEnd.lng, pEnd.lat)); opt = opt || {}; var opts = { type: 'image', url: url, opacity: .8 }; opts = Object.assign(opts, opt); var imgOverlay = new BMapGL.GroundOverlay(bounds, opts); return imgOverlay; } // 定义事件 function addEvent(overlay) { overlay.addEventListener('onclick', function (e) { if (e.value) { console.log('当前鼠标点高程:' + e.value + '米'); } }); overlay.addEventListener('onmousemove', function (e) { var color = this.getImagePixel(e.point); var value = this.getValue(color); if (value) { console.log('当前鼠标点高程:' + value + '米'); } }); } // 输入像素个性化相关的参数 var overlayImage = drawImage(115.42998374165875, 39.445598832357135, 117.51344540762456, 41.06713175601481, 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem/dem-bj.png', { isPixelMap: true, pixelMap: { fomularC: `float generateValue(vec4 rgb){ return rgb.r * 255. + rgb.g * 255. * 256. + rgb.b * 255. * 65536.;; }`, fomularJS: function (rgb) { return rgb.r + rgb.g * 256 + rgb.b * 65536; }, domain: [0, 2162], maskPng: 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem/beijingMask.png', maskData: 1, // 昌平区 colors: ['#268b9c', '#4150d5', '#d65db1', '#cb5025', '#c20a35'], positions: [0, 0.2, 0.6, 0.8, 1.0] } }); // 覆盖物添加到地图 map.addOverlay(overlayImage); // 注册事件 addEvent(overlayImage);
2基于三方标准图层
var map = new BMapGL.Map("container"); map.enableScrollWheelZoom(true); map.centerAndZoom(new BMapGL.Point(116.47153407391221, 40.260579778320434), 10); // 实例PixelLayer var pixelLayer = new BMapGL.PixelLayer({ pixelMap: { opacity: 1, fomularC: ` float generateValue(vec4 rgb){ return rgb.r * 255. + rgb.g * 255. * 256. + rgb.b * 255. * 65536.; } `, fomularJS: function (rgb) { return rgb.r + rgb.g * 256 + rgb.b * 65536; }, domain: [0, 2162], maskPng: 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem/beijingMask.png', maskCoord: [new BMapGL.Point(115.42998374165875, 39.445598832357135), new BMapGL.Point(117.51344540762456, 41.06713175601481)] }, // 下面为XYZLayer相关参数 tms: true, useThumbData: false, minZoom: 7, maxZoom: 12, tileUrlTemplate: 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem-bj-1/[z]/[x]/[y].png', extent: [12848170.946, 4784619.585, 13080078.854, 5021093.159] // "EPSG":3857 左下角坐标,右上角坐标 }); // 定义事件 function addEvent(overlay) { overlay.addEventListener('onclick', function (e) { if (e.value) { console.log('当前鼠标点高程:' + e.value + '米'); } }); overlay.addEventListener('onmousemove', function (e) { var color = this.getImagePixel(e.point); var value = this.getValue(color); if (value) { console.log('当前鼠标点高程:' + value + '米'); } }); } // 覆盖物添加到地图 map.addOverlay(pixelLayer); // 注册事件 addEvent(pixelLayer);
3MapVGL像素图层
图像数据源
// 需要引入MapVGL相关依赖 var map = initMap({ center: [116, 40], zoom: 10 }); var view = new mapvgl.View({ map: map }); var pixelLayer = new mapvgl.PixelLayer({ source:{ image: 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem/dem-bj.png' }, domain: [0, 2162], noData: -32768, // 不显示数据 baseLine: 0, elevationScale: 10, opacity: .75, isTerrain:true, gridRowMax: 100, gridColMax: 100, fomularC: ` float generateValue(vec4 rgb){ return rgb.r * 255. + rgb.g * 255. * 256. + rgb.b * 255. * 65536.; } `, fomularJS: function (rgb) { return rgb.r + rgb.g * 256 + rgb.b * 65536; }, // refImage: { // url: 'https://mapopen-pub-jsapigl.bj.bcebos.com/dem/rgb-bj.png', // noTextureData: [0, 0, 0], // }, refColors: { colors: [ '#F9F871','#FFC75F', '#FF9671','#FF6F91', '#D65DB1', '#845EC2'], positions: [0, 0.2, 0.4, 0.6, 0.8, 1.0] }, depthTest:true, depthMask:true, enablePicked: true, onClick: e => { console.log('当前鼠标点高程:' + e.dataIndex + '米'); }, onMousemove: e => { console.log('当前鼠标点高程:' + e.dataIndex + '米'); } }); // 百度经纬度坐标 var tileBounds = [115.42998373729408, 39.44559883470555, 117.5134454103027, 41.06713175801901]; // 设置图像范围 pixelLayer.setData([{ geometry: { "type": "Polygon", "coordinates": [[ [tileBounds[0], tileBounds[1], 0], [tileBounds[0], tileBounds[3], 0], [tileBounds[2], tileBounds[3], 0], [tileBounds[2], tileBounds[1], 0] ]] } }]); view.addLayer(pixelLayer);
ArrayBuffer数据源
如果是tif文件数据源,可以使用GeoTIFF JavaScript库[1]进行解析。如果是服务器端传到前端的ArrayBuffer直接解析输入即可.
const response = await fetch('http://mapopen-pub-jsapigl.bj.bcebos.com/dem/beijing_dem.tif'); const arrayBuffer = await response.arrayBuffer(); const tiff = await GeoTIFF.fromArrayBuffer(arrayBuffer); const image = await tiff.getImage(); const data = await image.readRasters(); var pixelLayer = new mapvgl.PixelLayer({ source:{ image: data[0], width: data.width, height: data.height }, fomularC: ` float generateValue(vec4 rgb){ return rgb.r; } `, fomularJS: function (rgb) { return rgb.r; }, // 其他配置可参考图像数据源配置 })