44import mapboxgl from 'mapbox-gl' ;
55import { Util as CommonUtil } from '@supermap/iclient-common/commontypes/Util' ;
66import { VideoLayerRenderer } from '@supermap/iclient-common/overlay/video/VideoLayerRenderer' ;
7+ import { bbox , polygon } from '@turf/turf' ;
78
89/**
910 * @class VideoLayer
1011 * @category Visualization Video
1112 * @modulecategory Overlay
1213 * @param {Object } options - 构造参数。
13- * @param {string } [ options.id] - 专题图层 ID。默认使用 CommonUtil.createUniqueID("VideoLayer_") 创建专题图层 ID 。
14- * @param {string } [ options.url] - 视频 或 流链接。支持 flv, m3u8 流格式 。
15- * @param {string } [options.extent ] - 视频范围 。
14+ * @param {string } options.url - 视频 或 流链接。支持 flv, m3u8 流格式 。
15+ * @param {Array } options.extent - 视频范围 。
16+ * @param {string } [options.id ] - 视频图层 ID。默认使用 CommonUtil.createUniqueID("VideoLayer_") 创建专题图层 ID 。
1617 * @extends {mapboxgl.Evented }
1718 * @usage
1819 */
@@ -24,8 +25,12 @@ export class VideoLayer extends mapboxgl.Evented {
2425 this . options = _options ;
2526 this . url = this . options . url ;
2627 this . extent = this . options . extent ;
28+ this . cv = this . options . opencv || window . cv ;
29+ if ( ! this . cv ) {
30+ throw new Error ( 'opencv.js is not existed!' ) ;
31+ }
2732 this . id = _options . id ? _options . id : CommonUtil . createUniqueID ( "VideoLayer_" ) ;
28- this . layerId = this . id + 'outer ' ;
33+ this . layerId = this . id + '_outer ' ;
2934 this . type = 'custom' ;
3035 this . renderingMode = '3d' ;
3136 this . overlay = true ;
@@ -44,7 +49,11 @@ export class VideoLayer extends mapboxgl.Evented {
4449 this . video . play ( ) ;
4550 } ) ;
4651 this . video . one ( 'ready' , ( ) => {
52+ setTimeout ( ( ) => {
53+ this . videoWidth = this . video . videoWidth ( ) ;
54+ this . videoHeight = this . video . videoHeight ( ) ;
4755 this . _addVideoLayer ( this . map ) ;
56+ } , 1000 ) ;
4857 } ) ;
4958 this . video . one ( 'canplay' , ( ) => {
5059 setTimeout ( ( ) => {
@@ -53,14 +62,77 @@ export class VideoLayer extends mapboxgl.Evented {
5362 } ) ;
5463 }
5564
56- render ( ) { }
65+ render ( ) { }
66+
67+ getPixelBbox ( map ) {
68+ let res = [ ] ;
69+ let minX = 0 ;
70+ let minY = 0 ;
71+ this . extent . forEach ( ( item ) => {
72+ let result = map . project ( item ) ;
73+ if ( ! minX || result . x < minX ) {
74+ minX = result . x ;
75+ }
76+ if ( ! minY || result . y < minY ) {
77+ minY = result . y ;
78+ }
79+ res . push ( result . x ) ;
80+ res . push ( result . y ) ;
81+ } ) ;
82+ res = res . map ( ( item , index ) => {
83+ if ( index % 2 === 0 ) {
84+ return item - minX ;
85+ } else {
86+ return item - minY ;
87+ }
88+ } ) ;
89+ return res ;
90+ }
5791
5892 _addVideoLayer ( map ) {
5993 let url = this . videoDomId || this . url ;
94+ this . pixelBBox = this . getPixelBbox ( map ) ;
95+ const result = bbox ( polygon ( [
96+ this . extent . concat ( this . extent [ 0 ] )
97+ ] ) ) ;
98+ let br = map . project ( [ result [ 2 ] , result [ 3 ] ] ) ;
99+ let tl = map . project ( [ result [ 0 ] , result [ 1 ] ] ) ;
100+ let size = [ Math . abs ( br . x - tl . x ) , Math . abs ( br . y - tl . y ) ] ;
101+ let ratio = size [ 0 ] / size [ 1 ] ;
102+ let realX = this . videoHeight * ratio ;
103+ let realY = this . videoHeight ;
104+ let ratioX = realX / size [ 0 ] ;
105+ let ratioY = realY / size [ 1 ] ;
106+ this . pixelBBox = this . pixelBBox . map ( ( item , index ) => {
107+ if ( index % 2 === 0 ) {
108+ return item * ratioX ;
109+ } else {
110+ return item * ratioY ;
111+ }
112+ } ) ;
113+ this . dsize = new this . cv . Size ( this . videoHeight * ratio , this . videoHeight ) ;
114+ let that = this ;
115+ let srcTri = this . cv . matFromArray ( 4 , 1 , this . cv . CV_32FC2 , [ 0 , 0 , that . videoWidth , 0 , that . videoWidth , that . videoHeight , 0 , that . videoHeight ] ) ;
116+ let dstTri = this . cv . matFromArray ( 4 , 1 , this . cv . CV_32FC2 , this . pixelBBox ) ;
60117 map . addSource ( this . layerId , {
61118 type : 'video' ,
62119 urls : [ url ] ,
63- coordinates : this . extent
120+ drawImageCallback ( frame ) {
121+ let src = that . cv . matFromImageData ( frame ) ;
122+ let dst = new that . cv . Mat ( ) ;
123+ let M = that . cv . findHomography ( srcTri , dstTri ) ;
124+ that . cv . warpPerspective ( src , dst , M , that . dsize ) ;
125+ let newFrame = new ImageData ( new Uint8ClampedArray ( dst . data ) , dst . cols , dst . rows ) ;
126+ src . delete ( ) ;
127+ dst . delete ( ) ;
128+ return newFrame ;
129+ } ,
130+ coordinates : [
131+ [ result [ 0 ] , result [ 3 ] ] ,
132+ [ result [ 2 ] , result [ 3 ] ] ,
133+ [ result [ 2 ] , result [ 1 ] ] ,
134+ [ result [ 0 ] , result [ 1 ] ]
135+ ]
64136 } ) ;
65137
66138 map . addLayer (
0 commit comments