4
4
import mapboxgl from 'mapbox-gl' ;
5
5
import { Util as CommonUtil } from '@supermap/iclient-common/commontypes/Util' ;
6
6
import { VideoLayerRenderer } from '@supermap/iclient-common/overlay/video/VideoLayerRenderer' ;
7
+ import { bbox , polygon } from '@turf/turf' ;
7
8
8
9
/**
9
10
* @class VideoLayer
10
11
* @category Visualization Video
11
12
* @modulecategory Overlay
12
13
* @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 。
16
17
* @extends {mapboxgl.Evented }
17
18
* @usage
18
19
*/
@@ -24,8 +25,12 @@ export class VideoLayer extends mapboxgl.Evented {
24
25
this . options = _options ;
25
26
this . url = this . options . url ;
26
27
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
+ }
27
32
this . id = _options . id ? _options . id : CommonUtil . createUniqueID ( "VideoLayer_" ) ;
28
- this . layerId = this . id + 'outer ' ;
33
+ this . layerId = this . id + '_outer ' ;
29
34
this . type = 'custom' ;
30
35
this . renderingMode = '3d' ;
31
36
this . overlay = true ;
@@ -44,7 +49,11 @@ export class VideoLayer extends mapboxgl.Evented {
44
49
this . video . play ( ) ;
45
50
} ) ;
46
51
this . video . one ( 'ready' , ( ) => {
52
+ setTimeout ( ( ) => {
53
+ this . videoWidth = this . video . videoWidth ( ) ;
54
+ this . videoHeight = this . video . videoHeight ( ) ;
47
55
this . _addVideoLayer ( this . map ) ;
56
+ } , 1000 ) ;
48
57
} ) ;
49
58
this . video . one ( 'canplay' , ( ) => {
50
59
setTimeout ( ( ) => {
@@ -53,14 +62,77 @@ export class VideoLayer extends mapboxgl.Evented {
53
62
} ) ;
54
63
}
55
64
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
+ }
57
91
58
92
_addVideoLayer ( map ) {
59
93
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 ) ;
60
117
map . addSource ( this . layerId , {
61
118
type : 'video' ,
62
119
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
+ ]
64
136
} ) ;
65
137
66
138
map . addLayer (
0 commit comments