1
- ( function ( ) { function r ( e , n , t ) { function o ( i , f ) { if ( ! n [ i ] ) { if ( ! e [ i ] ) { var c = "function" == typeof require && require ; if ( ! f && c ) return c ( i , ! 0 ) ; if ( u ) return u ( i , ! 0 ) ; var a = new Error ( "Cannot find module '" + i + "'" ) ; throw a . code = "MODULE_NOT_FOUND" , a } var p = n [ i ] = { exports :{ } } ; e [ i ] [ 0 ] . call ( p . exports , function ( r ) { var n = e [ i ] [ 1 ] [ r ] ; return o ( n || r ) } , p , p . exports , r , e , n , t ) } return n [ i ] . exports } for ( var u = "function" == typeof require && require , i = 0 ; i < t . length ; i ++ ) o ( t [ i ] ) ; return o } return r } ) ( ) ( { 1 :[ function ( require , module , exports ) {
1
+ ( function ( ) { function e ( t , n , r ) { function s ( o , u ) { if ( ! n [ o ] ) { if ( ! t [ o ] ) { var a = typeof require == "function" && require ; if ( ! u && a ) return a ( o , ! 0 ) ; if ( i ) return i ( o , ! 0 ) ; var f = new Error ( "Cannot find module '" + o + "'" ) ; throw f . code = "MODULE_NOT_FOUND" , f } var l = n [ o ] = { exports :{ } } ; t [ o ] [ 0 ] . call ( l . exports , function ( e ) { var n = t [ o ] [ 1 ] [ e ] ; return s ( n ?n :e ) } , l , l . exports , e , t , n , r ) } return n [ o ] . exports } var i = typeof require == "function" && require ; for ( var o = 0 ; o < r . length ; o ++ ) s ( r [ o ] ) ; return s } return e } ) ( ) ( { 1 :[ function ( require , module , exports ) {
2
+ /* todo - make sure proj4 calculations are being cached */
2
3
let chroma = require ( "chroma-js" ) ;
3
4
4
5
let L = window . L ;
6
+ let proj4 = window . proj4 ;
5
7
6
8
var GeoRasterLayer = L . GridLayer . extend ( {
7
9
@@ -36,18 +38,36 @@ var GeoRasterLayer = L.GridLayer.extend({
36
38
this . _ymin = georaster . ymin ;
37
39
this . _xmax = georaster . xmax ;
38
40
this . _ymax = georaster . ymax ;
41
+ this . _projection = georaster . projection ;
39
42
40
43
if ( georaster . sourceType === 'url' && georaster . numberOfRasters === 1 && ! options . pixelValueToColorFn ) {
41
44
// For COG, we can't determine a data min max for color scaling,
42
45
// so pixelValueToColorFn is required.
43
46
throw "pixelValueToColorFn is a required option for single-band rasters initialized via URL" ;
44
47
}
45
48
49
+ const projstr = georaster . projection . toString ( ) ;
46
50
console . log ( "georaster.ymin:" , georaster . ymin ) ;
47
- let southWest = L . latLng ( georaster . ymin , georaster . xmin ) ;
48
- let northEast = L . latLng ( georaster . ymax , georaster . xmax ) ;
49
- this . _bounds = L . latLngBounds ( southWest , northEast ) ;
50
- console . log ( "this._bounds:" , this . _bounds ) ;
51
+ if ( projstr === '4326' ) {
52
+ const southWest = L . latLng ( georaster . ymin , georaster . xmin ) ;
53
+ const northEast = L . latLng ( georaster . ymax , georaster . xmax ) ;
54
+ this . _bounds = L . latLngBounds ( southWest , northEast ) ;
55
+ } else if ( projstr . startsWith ( "326" ) || projstr . startsWith ( "327" ) ) {
56
+ /* using UTM Grid Projection */
57
+ if ( ! proj4 ) {
58
+ throw "proj4 must be found in the global scope in order to load a raster that uses a UTM projection" ;
59
+ }
60
+ const zone = projstr . substring ( 3 ) ;
61
+ const hemisphere = projstr . startsWith ( "326" ) ? "N" : projstr . startsWith ( "327" ) ? "S" : '' ;
62
+ this . projector = proj4 ( `+proj=utm +zone=${ zone } ${ hemisphere === 'S' ? ' +south ' : ' ' } +ellps=WGS84 +datum=WGS84 +units=m +no_defs` , 'EPSG:4326' ) ;
63
+ const bottomLeft = this . projector . forward ( { x : georaster . xmin , y : georaster . ymin } ) ;
64
+ const southWest = L . latLng ( bottomLeft . y , bottomLeft . x ) ;
65
+ const topRight = this . projector . forward ( { x : georaster . xmax , y : georaster . ymax } ) ;
66
+ const northEast = L . latLng ( topRight . y , topRight . x ) ;
67
+ this . _bounds = L . latLngBounds ( southWest , northEast ) ;
68
+ } else {
69
+ throw "georaster-layer-for-leaflet does not support rasters with the current georaster's projection" ;
70
+ }
51
71
options . bounds = this . _bounds ;
52
72
L . setOptions ( this , options ) ;
53
73
@@ -63,68 +83,84 @@ var GeoRasterLayer = L.GridLayer.extend({
63
83
console . error ( "ERROR initializing GeoTIFFLayer" , error ) ;
64
84
}
65
85
} ,
66
-
67
- getRasters : async function (
68
- map , tileNwPoint , height_of_rectangle_in_pixels , width_of_rectangle_in_pixels ,
69
- coords , pixelHeight , pixelWidth , number_of_rectangles_across , number_of_rectangles_down , ymax , xmin ) {
86
+
87
+ getRasters : function ( options ) {
88
+ const {
89
+ tileNwPoint,
90
+ height_of_rectangle_in_pixels,
91
+ width_of_rectangle_in_pixels,
92
+ coords,
93
+ number_of_rectangles_across,
94
+ number_of_rectangles_down,
95
+ ymax,
96
+ xmin
97
+ } = options ;
98
+ console . log ( "starting getRasters with options:" , options ) ;
70
99
// called if georaster was constructed from URL and we need to get
71
100
// data separately for each tile
72
101
// aka "COG mode"
73
102
74
- const raster_coords_for_tile_coords = function ( h , w ) {
75
- let y_center_in_map_pixels = tileNwPoint . y + ( h + 0.5 ) * height_of_rectangle_in_pixels ;
76
- let latWestPoint = L . point ( tileNwPoint . x , y_center_in_map_pixels ) ;
77
- let latWest = map . unproject ( latWestPoint , coords . z ) ;
78
- let { lat } = latWest ;
79
- let y_in_tile_pixels = Math . round ( h * height_of_rectangle_in_pixels ) ;
80
- let y_in_raster_pixels = Math . floor ( ( ymax - lat ) / pixelHeight ) ;
103
+ /*
104
+ This function takes in coordinates in the rendered image tile and
105
+ returns the y and x values in the original raster
106
+ */
107
+ const raster_coords_for_tile_coords = ( h , w ) => {
81
108
82
- let latLngPoint = L . point ( tileNwPoint . x + ( w + 0.5 ) * width_of_rectangle_in_pixels , y_center_in_map_pixels ) ;
83
- let latLng = map . unproject ( latLngPoint , coords . z ) ;
84
- let { lng } = latLng ;
85
- let x_in_raster_pixels = Math . floor ( ( lng - xmin ) / pixelWidth ) ;
109
+ const x_center_in_map_pixels = tileNwPoint . x + ( w + 0.5 ) * width_of_rectangle_in_pixels ;
110
+ const y_center_in_map_pixels = tileNwPoint . y + ( h + 0.5 ) * height_of_rectangle_in_pixels ;
86
111
87
- return [ y_in_raster_pixels , x_in_raster_pixels ] ;
88
- }
112
+ const mapPoint = L . point ( x_center_in_map_pixels , y_center_in_map_pixels ) ;
113
+ console . log ( "mapPoint:" , mapPoint ) ;
89
114
90
- let result = raster_coords_for_tile_coords ( 0 , 0 ) ;
91
- let [ min_y , min_x ] = result ;
92
- result = raster_coords_for_tile_coords ( number_of_rectangles_down - 1 , number_of_rectangles_across - 1 ) ;
93
- let [ max_y , max_x ] = result ;
115
+ const { lat, lng } = this . _map . unproject ( mapPoint , coords . z ) ;
94
116
95
- // careful not to flip min_y/max_y here
96
- let tile_values = await this . georaster . getValues ( min_x , min_y , max_x , max_y , number_of_rectangles_across , number_of_rectangles_down ) ;
97
-
98
- let tile_values_2d = tile_values . map ( valuesInOneDimension => {
99
- const valuesInTwoDimensions = [ ] ;
100
- const width = number_of_rectangles_across ;
101
- const height = number_of_rectangles_down ;
102
- for ( let y = 0 ; y < height ; y ++ ) {
103
- const start = y * width ;
104
- const end = start + width ;
105
- valuesInTwoDimensions . push ( valuesInOneDimension . slice ( start , end ) ) ;
117
+ if ( this . projection === 4326 ) {
118
+ return {
119
+ y : Math . floor ( ( ymax - lat ) / this . _pixelHeight ) ,
120
+ x : Math . floor ( ( lng - xmin ) / this . _pixelWidth )
121
+ }
122
+ } else if ( this . projector ) {
123
+ /* source raster doesn't use latitude and longitude,
124
+ so need to reproject point from lat/long to projection of raster
125
+ */
126
+ const [ x , y ] = this . projector . inverse ( [ lng , lat ] ) ;
127
+ return {
128
+ y : Math . floor ( ( ymax - y ) / this . _pixelHeight ) ,
129
+ x : Math . floor ( ( x - xmin ) / this . _pixelWidth )
130
+ }
106
131
}
107
- return valuesInTwoDimensions ;
108
- } ) ;
132
+ }
109
133
110
- return tile_values_2d ;
134
+ // careful not to flip min_y/max_y here
135
+ let topLeft = raster_coords_for_tile_coords ( 0 , 0 ) ;
136
+ let bottomRight = raster_coords_for_tile_coords ( number_of_rectangles_down - 1 , number_of_rectangles_across - 1 ) ;
137
+
138
+ const getValuesOptions = {
139
+ bottom : bottomRight . y ,
140
+ height : number_of_rectangles_down ,
141
+ left : topLeft . x ,
142
+ right : bottomRight . x ,
143
+ top : topLeft . y ,
144
+ width : number_of_rectangles_across
145
+ } ;
146
+ console . log ( "getValuesOptions:" , getValuesOptions ) ;
147
+ return this . georaster . getValues ( getValuesOptions ) ;
111
148
} ,
112
149
113
150
createTile : function ( coords , done ) {
114
151
115
152
var error ;
116
153
117
- let debug_level = 0 ;
154
+ let debug_level = 1 ;
118
155
119
156
if ( debug_level >= 1 ) {
120
- var start_time = performance . now ( ) ;
157
+ var start_time = window . performance . now ( ) ;
121
158
var duration_reading_rasters = 0 ;
122
159
var time_started_reading_rasters ;
123
160
var time_started_filling_rect ;
124
161
var duration_filling_rects = 0 ;
125
162
}
126
163
127
-
128
164
/*
129
165
Unpacking values for use later.
130
166
We do this in order to increase speed.
@@ -143,22 +179,20 @@ var GeoRasterLayer = L.GridLayer.extend({
143
179
let xmax = this . _xmax ;
144
180
let ymax = this . _ymax ;
145
181
146
- //if (debug_level >= 1) console.group();
147
-
148
- //if (debug_level >= 1) console.log("starting createTile with coords:", coords);
149
-
182
+ if ( debug_level >= 1 ) {
183
+ console . log ( "starting createTile with coords:" , coords ) ;
184
+ }
150
185
151
186
// create a <canvas> element for drawing
152
187
let tile = L . DomUtil . create ( 'canvas' , 'leaflet-tile' ) ;
153
188
tile . height = this . _tile_height ;
154
189
tile . width = this . _tile_width ;
155
190
156
-
157
191
// get a canvas context and draw something on it using coords.x, coords.y and coords.z
158
192
let context = tile . getContext ( '2d' ) ;
159
193
160
194
let bounds = this . _tileCoordsToBounds ( coords ) ;
161
- // if (debug_level >= 1) console.log("bounds:", bounds);
195
+ if ( debug_level >= 1 ) console . log ( "bounds:" , bounds ) ;
162
196
163
197
let xmin_of_tile = bounds . getWest ( ) ;
164
198
let xmax_of_tile = bounds . getEast ( ) ;
@@ -168,8 +202,25 @@ var GeoRasterLayer = L.GridLayer.extend({
168
202
169
203
let resolution = this . options . resolution ;
170
204
171
- let raster_pixels_across = Math . ceil ( ( xmax_of_tile - xmin_of_tile ) / pixelWidth ) ;
172
- let raster_pixels_down = Math . ceil ( ( ymax_of_tile - ymin_of_tile ) / pixelHeight ) ;
205
+ console . log ( "this.projection:" , this . _projection ) ;
206
+ let raster_pixels_across , raster_pixels_down ;
207
+ if ( this . _projection === 4326 ) {
208
+ // width of the tile in pixels from original raster
209
+ raster_pixels_across = Math . ceil ( ( xmax_of_tile - xmin_of_tile ) / pixelWidth ) ;
210
+ raster_pixels_down = Math . ceil ( ( ymax_of_tile - ymin_of_tile ) / pixelHeight ) ;
211
+ } else if ( this . projector ) {
212
+ /*
213
+ 1) convert top left to orginal values and top right to src values and divide by pixelWidth
214
+ */
215
+ const topLeft = this . projector . inverse ( { x : xmin_of_tile , y : ymax_of_tile } ) ;
216
+ const topRight = this . projector . inverse ( { x : xmax_of_tile , y : ymax_of_tile } ) ;
217
+ const bottomLeft = this . projector . inverse ( { x : xmin_of_tile , y : ymin_of_tile } ) ;
218
+ const bottomRight = this . projector . inverse ( { x : xmax_of_tile , y : ymin_of_tile } ) ;
219
+ raster_pixels_across = Math . ceil ( Math . max ( topRight . x - topLeft . x , bottomRight . x - bottomLeft . x ) / pixelWidth ) ;
220
+ raster_pixels_down = Math . ceil ( Math . max ( topLeft . y - bottomLeft . y , topRight . y - bottomRight . y ) / pixelHeight ) ;
221
+ }
222
+
223
+ // just making sure that that resolution isn't higher than the actual number of pixels
173
224
let number_of_rectangles_across = Math . min ( resolution , raster_pixels_across ) ;
174
225
let number_of_rectangles_down = Math . min ( resolution , raster_pixels_down ) ;
175
226
@@ -187,19 +238,21 @@ var GeoRasterLayer = L.GridLayer.extend({
187
238
188
239
//if (debug_level >= 1) console.log("ymax of raster:", ymax);
189
240
190
- let number_of_pixels_per_rectangle = this . _tile_width / 8 ;
191
-
192
241
let map = this . _map ;
193
242
let tileSize = this . getTileSize ( ) ;
243
+ // this converts tile coordinates (like how many tiles down and right)
244
+ // to pixels from left and top of tile pane
194
245
let tileNwPoint = coords . scaleBy ( tileSize ) ;
195
246
196
247
// render asynchronously so tiles show up as they finish instead of all at once (which blocks the UI)
197
248
setTimeout ( async function ( ) {
198
249
let tile_rasters = null ;
199
250
if ( ! rasters ) {
200
- tile_rasters = await this . getRasters (
201
- map , tileNwPoint , height_of_rectangle_in_pixels , width_of_rectangle_in_pixels , coords , pixelHeight , pixelWidth ,
202
- number_of_rectangles_across , number_of_rectangles_down , ymax , xmin ) ;
251
+ tile_rasters = await this . getRasters ( {
252
+ tileNwPoint, height_of_rectangle_in_pixels,
253
+ width_of_rectangle_in_pixels, coords, pixelHeight, pixelWidth,
254
+ number_of_rectangles_across, number_of_rectangles_down, ymax, xmin} ) ;
255
+ console . log ( "tile_rasters:" , tile_rasters ) ;
203
256
}
204
257
205
258
for ( let h = 0 ; h < number_of_rectangles_down ; h ++ ) {
@@ -220,7 +273,7 @@ var GeoRasterLayer = L.GridLayer.extend({
220
273
//if (debug_level >= 2) L.circleMarker([lat, lng], {color: "#00FF00"}).bindTooltip(h+","+w).addTo(this._map).openTooltip();
221
274
let x_in_raster_pixels = Math . floor ( ( lng - xmin ) / pixelWidth ) ;
222
275
223
- if ( debug_level >= 1 ) time_started_reading_rasters = performance . now ( ) ;
276
+ if ( debug_level >= 1 ) time_started_reading_rasters = window . performance . now ( ) ;
224
277
let values = null ;
225
278
if ( tile_rasters ) {
226
279
// get value from array specific to this tile
@@ -229,7 +282,7 @@ var GeoRasterLayer = L.GridLayer.extend({
229
282
// get value from array with data for entire raster
230
283
values = rasters . map ( raster => raster [ y_in_raster_pixels ] [ x_in_raster_pixels ] ) ;
231
284
}
232
- if ( debug_level >= 1 ) duration_reading_rasters += performance . now ( ) - time_started_reading_rasters ;
285
+ if ( debug_level >= 1 ) duration_reading_rasters += window . performance . now ( ) - time_started_reading_rasters ;
233
286
234
287
let color = null ;
235
288
if ( this . options . pixelValueToColorFn ) {
@@ -253,9 +306,9 @@ var GeoRasterLayer = L.GridLayer.extend({
253
306
//context.fillStyle = this.getColor(color);
254
307
if ( color ) {
255
308
context . fillStyle = color ;
256
- if ( debug_level >= 1 ) time_started_filling_rect = performance . now ( ) ;
309
+ if ( debug_level >= 1 ) time_started_filling_rect = window . performance . now ( ) ;
257
310
context . fillRect ( Math . round ( w * width_of_rectangle_in_pixels ) , y_in_tile_pixels , width_of_rectangle_in_pixels_int , height_of_rectangle_in_pixels_int ) ;
258
- if ( debug_level >= 1 ) duration_filling_rects += performance . now ( ) - time_started_filling_rect ;
311
+ if ( debug_level >= 1 ) duration_filling_rects += window . performance . now ( ) - time_started_filling_rect ;
259
312
}
260
313
//if (debug_level >= 2) console.log("filling:", [w * width_of_rectangle_in_pixels, rect_y_in_pixels, width_of_rectangle_in_pixels_int, height_of_rectangle_in_pixels_int]);
261
314
//if (debug_level >= 2) console.log("with color:", color);
@@ -269,7 +322,7 @@ var GeoRasterLayer = L.GridLayer.extend({
269
322
270
323
271
324
if ( debug_level >= 1 ) {
272
- let duration = performance . now ( ) - start_time ;
325
+ let duration = window . performance . now ( ) - start_time ;
273
326
console . log ( "creating tile took " , duration , "milliseconds" ) ;
274
327
console . log ( "took" , duration_reading_rasters , "milliseconds to read rasters, which is " , Math . round ( duration_reading_rasters / duration * 100 ) , "percentage of the total time" ) ;
275
328
console . log ( "took" , duration_filling_rects , "milliseconds to fill rects, which is " , Math . round ( duration_filling_rects / duration * 100 ) , "percentage of the total time" ) ;
@@ -285,14 +338,14 @@ var GeoRasterLayer = L.GridLayer.extend({
285
338
286
339
// method from https://github.com/Leaflet/Leaflet/blob/bb1d94ac7f2716852213dd11563d89855f8d6bb1/src/layer/ImageOverlay.js
287
340
getBounds : function ( ) {
288
- return this . _bounds ;
341
+ return this . _bounds ;
289
342
} ,
290
343
291
344
getColor ( name ) {
292
- let d = document . createElement ( "div" ) ;
293
- d . style . color = name ;
294
- document . body . appendChild ( d )
295
- return window . getComputedStyle ( d ) . color
345
+ let d = document . createElement ( "div" ) ;
346
+ d . style . color = name ;
347
+ document . body . appendChild ( d )
348
+ return window . getComputedStyle ( d ) . color
296
349
}
297
350
298
351
} ) ;
@@ -458,7 +511,7 @@ if (typeof window !== "undefined") {
458
511
root . chroma = chroma ;
459
512
}
460
513
461
- chroma . version = '1.4.1 ' ;
514
+ chroma . version = '1.4.0 ' ;
462
515
463
516
_input = { } ;
464
517
@@ -2424,7 +2477,7 @@ if (typeof window !== "undefined") {
2424
2477
if ( bypassMap == null ) {
2425
2478
bypassMap = false ;
2426
2479
}
2427
- if ( isNaN ( val ) || val === null ) {
2480
+ if ( isNaN ( val ) ) {
2428
2481
return _nacol ;
2429
2482
}
2430
2483
if ( ! bypassMap ) {
@@ -2664,14 +2717,6 @@ if (typeof window !== "undefined") {
2664
2717
return _gamma ;
2665
2718
}
2666
2719
} ;
2667
- f . nodata = function ( d ) {
2668
- if ( d != null ) {
2669
- _nacol = chroma ( d ) ;
2670
- return f ;
2671
- } else {
2672
- return _nacol ;
2673
- }
2674
- } ;
2675
2720
return f ;
2676
2721
} ;
2677
2722
0 commit comments