diff --git a/index.html b/index.html index 1b2738b..c24651b 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,7 @@ + @@ -246,4 +247,4 @@ } - + \ No newline at end of file diff --git a/index.html b/index.html index 1b2738b..c24651b 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,7 @@ + @@ -246,4 +247,4 @@ } - + \ No newline at end of file diff --git a/public/static/libs/mapbox/RainsLayer.js b/public/static/libs/mapbox/RainsLayer.js new file mode 100644 index 0000000..a3c9f2f --- /dev/null +++ b/public/static/libs/mapbox/RainsLayer.js @@ -0,0 +1,161 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? (module.exports = factory()) + : typeof define === 'function' && define.amd + ? define(factory) + : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), (global.mapboxgl1.RainsLayer = factory())); +})(window, function () { + async function urlToFile(url, fileName) { + // 使用 fetch 获取图片并转换为 Blob + const response = await fetch(url); + const blob = await response.blob(); + // 将 Blob 转换为 File 对象 + const file = new File([blob], fileName, { type: blob.type }); + return file; + } + const createCanvas = id => { + let canvas = document.createElement('canvas'); + canvas.id = 'canvas' + id; + canvas.style.display = 'none'; + document.body.append(canvas); + return canvas; + }; + const createPlot = async (e, canvas, scaleKey, plot) => { + var tif = await GeoTIFF.fromArrayBuffer(e.target.result); + var tifImg = await tif.getImage(); + var readRasters = await tifImg.readRasters(); + plot == null && + (plot = new plotty.plot({ + canvas, + data: readRasters[0], + width: tifImg.getWidth(), + height: tifImg.getHeight(), + domain: [0, 256], + colorScale: scaleKey, + })); + plot.setData(readRasters[0], tifImg.getWidth(), tifImg.getHeight()); + plot.render(); + }; + const createCanvasLayer = (canvasId, i, bbox, map) => { + bbox = [ + [bbox[0], bbox[3]], + [bbox[2], bbox[3]], + [bbox[2], bbox[1]], + [bbox[0], bbox[1]], + ]; + if (map.getLayer('canvas-layer' + i)) { + map.removeLayer('canvas-layer' + i); + map.removeSource('canvas-source' + i); + } + map.addSource('canvas-source' + i, { type: 'canvas', canvas: canvasId, coordinates: bbox, animate: true }); + map.addLayer({ id: 'canvas-layer' + i, type: 'raster', source: 'canvas-source' + i }); + map.moveLayer('canvas-layer' + i); + }; + const plotInit = (name, colorScale = colorScale) => { + const minVal = colorScale[0].value; + const maxVal = colorScale[colorScale.length - 1].value; + let color = colorScale.filter(i => Number(i.value) / maxVal <= 1); + if (color[color.length - 1].value / maxVal < 1) color.push({ value: maxVal, color: colorScale[color.length].color }); + plotty.addColorScale( + name, + color.map(i => i.color), + color.map(i => (i.value / maxVal).toFixed(5)) + ); + }; + + const setRainImage = (file, canvas, scaleKey, plot) => { + var reader = new FileReader(); + reader.onload = e => createPlot(e, canvas, scaleKey, plot); + reader.readAsArrayBuffer(file); + }; + + return class RainsLayer { + map = null; + index = null; + bbox = null; + callback = null; + images = []; + imagesFiles = []; + canvas = null; + plot = null; + scales = { + 1: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 3: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 12: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 24: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + }; + constructor(bbox, images, callback) { + this.callback = callback; + this.bbox = bbox; + this.images = images; + this.init(); + } + + async init() { + if (this.bbox.length && this.images.length) { + Object.keys(this.scales).forEach(key => plotInit(key, this.scales[key])); + this.canvas = createCanvas(0); + this.imagesFiles = await Promise.all(this.images.map(url => urlToFile(url, _.last(_.split(url, '/'))))); + this.callback && this.callback(this); + } + } + + addTo(map) { + this.destroy(); + this.map = map; + createCanvasLayer(this.canvas.id, 0, this.bbox, map); + return this; + } + + next(scaleKey = 1) { + if (!this.index) this.index = 0; + this.index++; + if (this.index >= this.images.length) this.index = 0; + setRainImage(this.imagesFiles[this.index], this.canvas, scaleKey, this.plot); + } + + prev(scaleKey = 1) { + if (!this.index) this.index = 0; + this.index++; + if (this.index <= 0) this.index = this.imagesFiles.length; + setRainImage(this.imagesFiles[this.index - 1], this.canvas, scaleKey, this.plot); + } + + hide(newfiberMap) { + newfiberMap.map.setLayoutProperty('canvas-layer0', 'visibility', 'none'); + } + + show(newfiberMap) { + newfiberMap.map.setLayoutProperty('canvas-layer0', 'visibility', 'visible'); + } + + destroy() { + if (this.map && this.map.getLayer('canvas-layer0')) this.map.removeLayer('canvas-layer0'); + if (this.map && this.map.getSource('canvas-source0')) this.map.removeSource('canvas-source0'); + } + }; +}); diff --git a/index.html b/index.html index 1b2738b..c24651b 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,7 @@ + @@ -246,4 +247,4 @@ } - + \ No newline at end of file diff --git a/public/static/libs/mapbox/RainsLayer.js b/public/static/libs/mapbox/RainsLayer.js new file mode 100644 index 0000000..a3c9f2f --- /dev/null +++ b/public/static/libs/mapbox/RainsLayer.js @@ -0,0 +1,161 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? (module.exports = factory()) + : typeof define === 'function' && define.amd + ? define(factory) + : ((global = typeof globalThis !== 'undefined' ? globalThis : global || self), (global.mapboxgl1.RainsLayer = factory())); +})(window, function () { + async function urlToFile(url, fileName) { + // 使用 fetch 获取图片并转换为 Blob + const response = await fetch(url); + const blob = await response.blob(); + // 将 Blob 转换为 File 对象 + const file = new File([blob], fileName, { type: blob.type }); + return file; + } + const createCanvas = id => { + let canvas = document.createElement('canvas'); + canvas.id = 'canvas' + id; + canvas.style.display = 'none'; + document.body.append(canvas); + return canvas; + }; + const createPlot = async (e, canvas, scaleKey, plot) => { + var tif = await GeoTIFF.fromArrayBuffer(e.target.result); + var tifImg = await tif.getImage(); + var readRasters = await tifImg.readRasters(); + plot == null && + (plot = new plotty.plot({ + canvas, + data: readRasters[0], + width: tifImg.getWidth(), + height: tifImg.getHeight(), + domain: [0, 256], + colorScale: scaleKey, + })); + plot.setData(readRasters[0], tifImg.getWidth(), tifImg.getHeight()); + plot.render(); + }; + const createCanvasLayer = (canvasId, i, bbox, map) => { + bbox = [ + [bbox[0], bbox[3]], + [bbox[2], bbox[3]], + [bbox[2], bbox[1]], + [bbox[0], bbox[1]], + ]; + if (map.getLayer('canvas-layer' + i)) { + map.removeLayer('canvas-layer' + i); + map.removeSource('canvas-source' + i); + } + map.addSource('canvas-source' + i, { type: 'canvas', canvas: canvasId, coordinates: bbox, animate: true }); + map.addLayer({ id: 'canvas-layer' + i, type: 'raster', source: 'canvas-source' + i }); + map.moveLayer('canvas-layer' + i); + }; + const plotInit = (name, colorScale = colorScale) => { + const minVal = colorScale[0].value; + const maxVal = colorScale[colorScale.length - 1].value; + let color = colorScale.filter(i => Number(i.value) / maxVal <= 1); + if (color[color.length - 1].value / maxVal < 1) color.push({ value: maxVal, color: colorScale[color.length].color }); + plotty.addColorScale( + name, + color.map(i => i.color), + color.map(i => (i.value / maxVal).toFixed(5)) + ); + }; + + const setRainImage = (file, canvas, scaleKey, plot) => { + var reader = new FileReader(); + reader.onload = e => createPlot(e, canvas, scaleKey, plot); + reader.readAsArrayBuffer(file); + }; + + return class RainsLayer { + map = null; + index = null; + bbox = null; + callback = null; + images = []; + imagesFiles = []; + canvas = null; + plot = null; + scales = { + 1: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 3: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 12: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + 24: [ + { value: '0', color: 'rgba(7, 213, 118, 0)' }, + { value: '0.2', color: 'rgba(7, 213, 118, 1)' }, + { value: '5', color: 'rgba(38, 129, 240,1)' }, + { value: '25', color: 'rgba(255, 26, 26, 1)' }, + { value: '250', color: 'rgba(255, 26, 26, 1)' }, + ], + }; + constructor(bbox, images, callback) { + this.callback = callback; + this.bbox = bbox; + this.images = images; + this.init(); + } + + async init() { + if (this.bbox.length && this.images.length) { + Object.keys(this.scales).forEach(key => plotInit(key, this.scales[key])); + this.canvas = createCanvas(0); + this.imagesFiles = await Promise.all(this.images.map(url => urlToFile(url, _.last(_.split(url, '/'))))); + this.callback && this.callback(this); + } + } + + addTo(map) { + this.destroy(); + this.map = map; + createCanvasLayer(this.canvas.id, 0, this.bbox, map); + return this; + } + + next(scaleKey = 1) { + if (!this.index) this.index = 0; + this.index++; + if (this.index >= this.images.length) this.index = 0; + setRainImage(this.imagesFiles[this.index], this.canvas, scaleKey, this.plot); + } + + prev(scaleKey = 1) { + if (!this.index) this.index = 0; + this.index++; + if (this.index <= 0) this.index = this.imagesFiles.length; + setRainImage(this.imagesFiles[this.index - 1], this.canvas, scaleKey, this.plot); + } + + hide(newfiberMap) { + newfiberMap.map.setLayoutProperty('canvas-layer0', 'visibility', 'none'); + } + + show(newfiberMap) { + newfiberMap.map.setLayoutProperty('canvas-layer0', 'visibility', 'visible'); + } + + destroy() { + if (this.map && this.map.getLayer('canvas-layer0')) this.map.removeLayer('canvas-layer0'); + if (this.map && this.map.getSource('canvas-source0')) this.map.removeSource('canvas-source0'); + } + }; +}); diff --git a/public/static/libs/mapbox/style/floodOneMap.json b/public/static/libs/mapbox/style/floodOneMap.json index b0efcab..a46b332 100644 --- a/public/static/libs/mapbox/style/floodOneMap.json +++ b/public/static/libs/mapbox/style/floodOneMap.json @@ -528,7 +528,7 @@ "minzoom": 0, "maxzoom": 24, "mType": "geojsonMvt", - "columns": "id,color,pipediameter,deviceName,address,st_asText(geometrys) as geometry" + "columns": "id,color,level,address,st_asText(geometrys) as geometry" }, { "id": "pipeline_point",