@@ -44,6 +44,7 @@ var canvas_pixelmapFeature = function (arg) {
4444 object . call ( this ) ;
4545
4646 var m_quadFeature ,
47+ m_quadFeatureInit ,
4748 s_exit = this . _exit ,
4849 m_this = this ;
4950
@@ -59,21 +60,25 @@ var canvas_pixelmapFeature = function (arg) {
5960 * feature indices that are located at the specified point.
6061 */
6162 this . pointSearch = function ( geo , gcs ) {
62- if ( m_quadFeature && m_this . m_info ) {
63+ if ( m_quadFeature ) {
6364 var result = m_quadFeature . pointSearch ( geo , gcs ) ;
64- if ( result . index . length === 1 && result . extra && result . extra [ result . index [ 0 ] ] . basis ) {
65- var basis = result . extra [ result . index [ 0 ] ] . basis , x , y , idx ;
66- x = Math . floor ( basis . x * m_this . m_info . width ) ;
67- y = Math . floor ( basis . y * m_this . m_info . height ) ;
68- if ( x >= 0 && x < m_this . m_info . width &&
65+ if ( m_this . m_info ) {
66+ if ( result . index . length === 1 && result . extra && result . extra [ result . index [ 0 ] ] . basis ) {
67+ var basis = result . extra [ result . index [ 0 ] ] . basis , x , y , idx ;
68+ x = Math . floor ( basis . x * m_this . m_info . width ) ;
69+ y = Math . floor ( basis . y * m_this . m_info . height ) ;
70+ if ( x >= 0 && x < m_this . m_info . width &&
6971 y >= 0 && y < m_this . m_info . height ) {
70- idx = m_this . m_info . indices [ y * m_this . m_info . width + x ] ;
71- result = {
72- index : [ idx ] ,
73- found : [ m_this . data ( ) [ idx ] ]
74- } ;
75- return result ;
72+ idx = m_this . m_info . indices [ y * m_this . m_info . width + x ] ;
73+ result = {
74+ index : [ idx ] ,
75+ found : [ m_this . data ( ) [ idx ] ]
76+ } ;
77+ return result ;
78+ }
7679 }
80+ } else {
81+ return this . _pointSearchProcess ( result ) ;
7782 }
7883 }
7984 return { index : [ ] , found : [ ] } ;
@@ -84,41 +89,47 @@ var canvas_pixelmapFeature = function (arg) {
8489 * if the pixelmap has already been prepared (it is invalidated by a change
8590 * in the image).
8691 *
92+ * @param {object } [quad] A quad to use as the base instead of the class
93+ * instance.
8794 * @returns {geo.pixelmapFeature.info? }
8895 */
89- this . _preparePixelmap = function ( ) {
96+ this . _preparePixelmap = function ( quad ) {
97+ const base = quad || m_this ;
98+ if ( quad && quad . m_info ) {
99+ return quad . m_info ;
100+ }
90101 var i , idx , pixelData ;
91102
92- if ( ! util . isReadyImage ( m_this . m_srcImage ) ) {
103+ if ( ! util . isReadyImage ( base . m_srcImage ) ) {
93104 return undefined ;
94105 }
95- m_this . m_info = {
96- width : m_this . m_srcImage . naturalWidth ,
97- height : m_this . m_srcImage . naturalHeight ,
106+ base . m_info = {
107+ width : base . m_srcImage . naturalWidth ,
108+ height : base . m_srcImage . naturalHeight ,
98109 canvas : document . createElement ( 'canvas' )
99110 } ;
100111
101- m_this . m_info . canvas . width = m_this . m_info . width ;
102- m_this . m_info . canvas . height = m_this . m_info . height ;
103- m_this . m_info . context = m_this . m_info . canvas . getContext ( '2d' ) ;
112+ base . m_info . canvas . width = base . m_info . width ;
113+ base . m_info . canvas . height = base . m_info . height ;
114+ base . m_info . context = base . m_info . canvas . getContext ( '2d' ) ;
104115
105- m_this . m_info . context . drawImage ( m_this . m_srcImage , 0 , 0 ) ;
106- m_this . m_info . imageData = m_this . m_info . context . getImageData (
107- 0 , 0 , m_this . m_info . canvas . width , m_this . m_info . canvas . height ) ;
108- pixelData = m_this . m_info . imageData . data ;
109- m_this . m_info . indices = new Array ( pixelData . length / 4 ) ;
110- m_this . m_info . area = pixelData . length / 4 ;
116+ base . m_info . context . drawImage ( base . m_srcImage , 0 , 0 ) ;
117+ base . m_info . imageData = base . m_info . context . getImageData (
118+ 0 , 0 , base . m_info . canvas . width , base . m_info . canvas . height ) ;
119+ pixelData = base . m_info . imageData . data ;
120+ base . m_info . indices = new Array ( pixelData . length / 4 ) ;
121+ base . m_info . area = pixelData . length / 4 ;
111122
112- m_this . m_info . mappedColors = { } ;
123+ base . m_info . mappedColors = { } ;
113124 for ( i = 0 ; i < pixelData . length ; i += 4 ) {
114125 idx = pixelData [ i ] + ( pixelData [ i + 1 ] << 8 ) + ( pixelData [ i + 2 ] << 16 ) ;
115- m_this . m_info . indices [ i / 4 ] = idx ;
116- if ( ! m_this . m_info . mappedColors [ idx ] ) {
117- m_this . m_info . mappedColors [ idx ] = { first : i / 4 } ;
126+ base . m_info . indices [ i / 4 ] = idx ;
127+ if ( ! base . m_info . mappedColors [ idx ] ) {
128+ base . m_info . mappedColors [ idx ] = { first : i / 4 } ;
118129 }
119- m_this . m_info . mappedColors [ idx ] . last = i / 4 ;
130+ base . m_info . mappedColors [ idx ] . last = i / 4 ;
120131 }
121- return m_this . m_info ;
132+ return base . m_info ;
122133 } ;
123134
124135 /**
@@ -127,23 +138,43 @@ var canvas_pixelmapFeature = function (arg) {
127138 * these colors, then draw the resultant image as a quad.
128139 *
129140 * @fires geo.event.pixelmap.prepared
141+ * @param {object } [quad] A quad to use as the base instead of the class
142+ * instance.
130143 */
131- this . _computePixelmap = function ( ) {
144+ this . _computePixelmap = function ( quad ) {
145+ const base = quad || m_this ;
132146 var data = m_this . data ( ) || [ ] ,
133147 colorFunc = m_this . style . get ( 'color' ) ,
134148 i , idx , lastidx , color , pixelData , indices , mappedColors ,
135149 updateFirst , updateLast = - 1 , update , prepared ;
136150
137- if ( ! m_this . m_info ) {
151+ if ( ! m_quadFeatureInit && m_quadFeature && ! quad ) {
152+ m_quadFeature . _hookRenderImageQuads = ( quads ) => {
153+ quads . forEach ( ( quad ) => {
154+ if ( ! quad . m_srcImage ) {
155+ quad . m_srcImage = quad . image ;
156+ m_this . _computePixelmap ( quad ) ;
157+ quad . image = quad . m_info . context . canvas ;
158+ quad . _build = m_this . buildTime ( ) . timestamp ( ) ;
159+ } else if ( m_this . buildTime ( ) . timestamp ( ) > quad . _build ) {
160+ m_this . _computePixelmap ( quad ) ;
161+ quad . image = quad . m_info . context . canvas ;
162+ quad . _build = m_this . buildTime ( ) . timestamp ( ) ;
163+ }
164+ } ) ;
165+ } ;
166+ m_quadFeatureInit = true ;
167+ }
168+ if ( ! base . m_info ) {
138169 m_this . indexModified ( undefined , 'clear' ) ;
139- if ( ! m_this . _preparePixelmap ( ) ) {
170+ if ( ! m_this . _preparePixelmap ( quad ) ) {
140171 return ;
141172 }
142173 prepared = true ;
143174 }
144175 m_this . indexModified ( undefined , 'clear' ) ;
145- mappedColors = m_this . m_info . mappedColors ;
146- updateFirst = m_this . m_info . area ;
176+ mappedColors = base . m_info . mappedColors ;
177+ updateFirst = base . m_info . area ;
147178 for ( idx in mappedColors ) {
148179 if ( mappedColors . hasOwnProperty ( idx ) ) {
149180 color = colorFunc ( data [ idx ] , + idx ) || { } ;
@@ -171,8 +202,8 @@ var canvas_pixelmapFeature = function (arg) {
171202 return ;
172203 }
173204 /* Update only the extent that has changed */
174- pixelData = m_this . m_info . imageData . data ;
175- indices = m_this . m_info . indices ;
205+ pixelData = base . m_info . imageData . data ;
206+ indices = base . m_info . indices ;
176207 for ( i = updateFirst ; i <= updateLast ; i += 1 ) {
177208 idx = indices [ i ] ;
178209 if ( idx !== lastidx ) {
@@ -188,10 +219,13 @@ var canvas_pixelmapFeature = function (arg) {
188219 }
189220 }
190221 /* Place the updated area into the canvas */
191- m_this . m_info . context . putImageData (
192- m_this . m_info . imageData , 0 , 0 , 0 , Math . floor ( updateFirst / m_this . m_info . width ) ,
193- m_this . m_info . width , Math . ceil ( ( updateLast + 1 ) / m_this . m_info . width ) ) ;
222+ base . m_info . context . putImageData (
223+ base . m_info . imageData , 0 , 0 , 0 , Math . floor ( updateFirst / base . m_info . width ) ,
224+ base . m_info . width , Math . ceil ( ( updateLast + 1 ) / base . m_info . width ) ) ;
194225
226+ if ( quad ) {
227+ return ;
228+ }
195229 /* If we haven't made a quad feature, make one now. The quad feature needs
196230 * to have the canvas capability. */
197231 if ( ! m_quadFeature ) {
@@ -206,6 +240,7 @@ var canvas_pixelmapFeature = function (arg) {
206240 position : m_this . style . get ( 'position' ) } )
207241 . data ( [ { } ] )
208242 . draw ( ) ;
243+ m_quadFeatureInit = true ;
209244 }
210245 /* If we prepared the pixelmap and rendered it, send a prepared event */
211246 if ( prepared ) {
@@ -230,12 +265,18 @@ var canvas_pixelmapFeature = function (arg) {
230265 return m_this ;
231266 } ;
232267
268+ if ( arg . quadFeature ) {
269+ m_quadFeature = arg . quadFeature ;
270+ }
233271 this . _init ( arg ) ;
234272 return this ;
235273} ;
236274
237275inherit ( canvas_pixelmapFeature , pixelmapFeature ) ;
238276
239277// Now register it
240- registerFeature ( 'canvas' , 'pixelmap' , canvas_pixelmapFeature ) ;
278+ var capabilities = { } ;
279+ capabilities [ pixelmapFeature . capabilities . lookup ] = true ;
280+
281+ registerFeature ( 'canvas' , 'pixelmap' , canvas_pixelmapFeature , capabilities ) ;
241282module . exports = canvas_pixelmapFeature ;
0 commit comments