From a8af9c0ac969c343dfca672d49ade11ddc62f533 Mon Sep 17 00:00:00 2001 From: qiwei Date: Wed, 17 Apr 2024 20:35:44 +0800 Subject: [PATCH] add videolayer ut review by luox --- .../overlay/video/VideoLayerRenderer.js | 13 +- src/mapboxgl/overlay/VideoLayer.js | 12 +- src/mapboxgl/package.json | 1 + test/mapboxgl/overlay/VideoLayerSpec.js | 120 ++++++++++++++++++ test/test-main-mapboxgl.js | 1 + test/tool/mock_mapboxgl_map.js | 8 ++ 6 files changed, 146 insertions(+), 9 deletions(-) create mode 100644 test/mapboxgl/overlay/VideoLayerSpec.js diff --git a/src/common/overlay/video/VideoLayerRenderer.js b/src/common/overlay/video/VideoLayerRenderer.js index 08a005419..ab248304c 100644 --- a/src/common/overlay/video/VideoLayerRenderer.js +++ b/src/common/overlay/video/VideoLayerRenderer.js @@ -13,7 +13,7 @@ import 'videojs-flvjs-es6'; * @version 11.2.0 * @param {Object} options - 参数。 * @param {string} [options.id] - 图层 ID。 - * @param {Array} [options.extent] - 视频范围。 + * @param {string} [options.url] - 视频地址。 * @usage */ @@ -33,7 +33,10 @@ export class VideoLayerRenderer { video.setAttribute('crossorigin', 'anonymous'); document.body.appendChild(video); } - + /** + * @function VideoLayerRenderer.prototype.createVideo + * @description 创建videojs 实例。 + */ createVideo() { this._createVideoElement(); let options = this._getVideoOptions(); @@ -85,7 +88,11 @@ export class VideoLayerRenderer { return options; } - getVideoDom() { + /** + * @function VideoLayerRenderer.prototype.getVideoDomId + * @description 获取创建的 video 元素的 DOM id。 + */ + getVideoDomId() { if (!this.url) { return; } diff --git a/src/mapboxgl/overlay/VideoLayer.js b/src/mapboxgl/overlay/VideoLayer.js index 48d086b41..dca0b7ad1 100644 --- a/src/mapboxgl/overlay/VideoLayer.js +++ b/src/mapboxgl/overlay/VideoLayer.js @@ -11,9 +11,9 @@ import { bbox, polygon } from '@turf/turf'; * @category Visualization Video * @modulecategory Overlay * @param {Object} options - 构造参数。 - * @param {string} options.url - 视频 或 流链接。支持 flv, m3u8 流格式。 + * @param {string} options.url - 视频 或 流链接。支持 flv, m3u8, map4 格式。 * @param {Array} options.extent - 视频范围。 - * @param {Object} [options.opencv] - opencv.js 实例。 + * @param {Object} [options.opencv] - opencv.js 实例, 未传入时将去 window.cv 获取。 * @param {string} [options.id] - 视频图层 ID。默认使用 CommonUtil.createUniqueID("VideoLayer_") 创建专题图层 ID。 * @extends {mapboxgl.Evented} * @usage @@ -28,7 +28,7 @@ export class VideoLayer extends mapboxgl.Evented { this.extent = this.options.extent; this.cv = this.options.opencv || window.cv; if (!this.cv) { - throw new Error('opencv.js is not existed!'); + throw new Error('opencv.js instance is not existed!'); } this.id = _options.id ? _options.id : CommonUtil.createUniqueID("VideoLayer_"); this.layerId = this.id + '_outer'; @@ -45,7 +45,7 @@ export class VideoLayer extends mapboxgl.Evented { this.map = map; this.renderer = new VideoLayerRenderer({ url: this.url, id: this.layerId }); this.video = this.renderer.createVideo(); - this.videoDomId = this.renderer.getVideoDom(); + this.videoDomId = this.renderer.getVideoDomId(); this.video.one('firstplay', () => { this.video.play(); }); @@ -65,7 +65,7 @@ export class VideoLayer extends mapboxgl.Evented { render() {} - getPixelBbox(map) { + _getPixelBbox(map) { let res = []; let minX = 0; let minY = 0; @@ -92,7 +92,7 @@ export class VideoLayer extends mapboxgl.Evented { _addVideoLayer(map) { let url = this.videoDomId || this.url; - this.pixelBBox = this.getPixelBbox(map); + this.pixelBBox = this._getPixelBbox(map); const result = bbox(polygon([ this.extent.concat(this.extent[0]) ])); diff --git a/src/mapboxgl/package.json b/src/mapboxgl/package.json index ddf875f80..d63bc0439 100644 --- a/src/mapboxgl/package.json +++ b/src/mapboxgl/package.json @@ -15,6 +15,7 @@ "author": "SuperMap", "license": "Apache-2.0", "dependencies": { + "@turf/turf": "6.5.0", "mapv": "2.0.62", "mapbox-gl": "1.13.2", "three": "0.150.1", diff --git a/test/mapboxgl/overlay/VideoLayerSpec.js b/test/mapboxgl/overlay/VideoLayerSpec.js new file mode 100644 index 000000000..90090d723 --- /dev/null +++ b/test/mapboxgl/overlay/VideoLayerSpec.js @@ -0,0 +1,120 @@ +import { VideoLayer } from '../../../src/mapboxgl/overlay/VideoLayer'; +import mapboxgl from 'mapbox-gl'; +import mbglmap from '../../tool/mock_mapboxgl_map'; +var url = GlobeParameter.ChinaURL + '/zxyTileImage.png?z={z}&x={x}&y={y}'; +describe('mapboxgl_VideoLayer', () => { + var originalTimeout; + var testDiv, map; + beforeAll((done) => { + testDiv = window.document.createElement('div'); + testDiv.setAttribute('id', 'map'); + testDiv.style.styleFloat = 'left'; + testDiv.style.marginLeft = '8px'; + testDiv.style.marginTop = '50px'; + testDiv.style.width = '500px'; + testDiv.style.height = '500px'; + window.document.body.appendChild(testDiv); + spyOn(mapboxgl, 'Map').and.callFake(mbglmap); + map = new mapboxgl.Map({ + container: 'map', + style: { + version: 8, + sources: { + 'raster-tiles': { + type: 'raster', + tiles: [url], + tileSize: 256 + } + }, + layers: [ + { + id: 'simple-tiles', + type: 'raster', + source: 'raster-tiles', + minzoom: 0, + maxzoom: 22 + } + ] + }, + center: [0, 0], + zoom: 3 + }); + map.on('load', function () { + done(); + }); + }); + beforeEach(() => { + originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 50000; + }); + + afterEach(() => { + jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout; + }); + + afterAll(() => { + document.body.removeChild(testDiv); + map = null; + }); + + it('init videoLayer', (done) => { + var url = 'http://172.16.15.84:8000/live/test.flv'; + var cv = { + CV_32FC2: 'CV_32FC2', + matFromImageData: function () { + return { + delete: function () { + + } + } + }, + Size: function () { + return { + width: 770, + height: 690 + } + }, + matFromArray: function () { + + }, + Mat: function () { + return { + delete: function () { }, + cols: 2, + rows: 2, + data: [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4] + } + }, + findHomography: function () { + + }, + warpPerspective: function () { + + } + } + spyOn(cv, 'Size'); + spyOn(cv, 'findHomography'); + spyOn(cv, 'warpPerspective'); + var videoLayer = new VideoLayer({ + url: url, + opencv: cv, + extent: [ + [116.14394400766855, 28.249134537249257], + [116.143464581289, 28.252977295834056], + [116.14734767029731, 28.251762901914655], + [116.14737169684759, 28.25095489453961] + ] + }); + videoLayer.onAdd(map); + setTimeout(() => { + expect(cv.Size).toHaveBeenCalled(); + expect(cv.findHomography).toHaveBeenCalled(); + expect(cv.warpPerspective).toHaveBeenCalled(); + expect(videoLayer.url).toBe(url); + expect(videoLayer.videoDomId).not.toBeNull(); + expect(videoLayer.video).not.toBeNull(); + expect(videoLayer.pixelBBox).not.toBeNull(); + done(); + }, 3000); + }); +}); diff --git a/test/test-main-mapboxgl.js b/test/test-main-mapboxgl.js index 6b50c6353..a396c2715 100644 --- a/test/test-main-mapboxgl.js +++ b/test/test-main-mapboxgl.js @@ -38,6 +38,7 @@ import './mapboxgl/services/GeoRelationAnalysisSpec.js'; import './mapboxgl/services/GeometryBatchAnalysisSpec.js'; import './mapboxgl/services/GeoprocessingServiceSpec.js'; import './mapboxgl/overlay/FGBLayerSpec.js'; +import './mapboxgl/overlay/VideoLayerSpec.js'; import './mapboxgl/services/GetFeaturesByBoundsSpec.js'; import './mapboxgl/services/GetFeaturesByBufferSpec.js'; import './mapboxgl/services/GetFeaturesByGeometrySpec.js'; diff --git a/test/tool/mock_mapboxgl_map.js b/test/tool/mock_mapboxgl_map.js index e3d4fd186..891117c6e 100644 --- a/test/tool/mock_mapboxgl_map.js +++ b/test/tool/mock_mapboxgl_map.js @@ -128,6 +128,11 @@ const Map = function (options) { this.getSource = function (name) { this._sources[name]; + if (this._sources[name].type === 'video') { + return { + play: function() {} + } + } }; this.loaded = function () { @@ -141,6 +146,9 @@ const Map = function (options) { this.overlayLayersManager = {}; this.addSource = function (name, source) { + if (source && source.drawImageCallback) { + source.drawImageCallback(); + } this._sources[name] = source; }; this.removeSource = function (name) {