gridviz 3.0.10 → 3.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gridviz",
3
- "version": "3.0.10",
3
+ "version": "3.0.12",
4
4
  "description": "Visualization tool for gridded statistics",
5
5
  "keywords": [
6
6
  "statistics",
package/src/index.js CHANGED
@@ -56,8 +56,9 @@ export { TrivariateLegend } from './legend/TrivariateLegend.js'
56
56
  export * from './utils/stretching.js'
57
57
  export * from './utils/scale.js'
58
58
  export * from './utils/trivariate.js'
59
- export * from './utils/chernoff.js'
60
- export { nice, loadImage } from './utils/utils.js'
59
+ //export * from './utils/chernoff.js'
60
+ export { nice } from './utils/utils.js'
61
+ //loadImage
61
62
 
62
63
  import { GeoCanvas } from './core/GeoCanvas.js'
63
64
  export const getParameterByName = GeoCanvas.getParameterByName
@@ -29,11 +29,40 @@ export class GeoJSONLayer extends Layer {
29
29
  * @type {function(object):boolean} */
30
30
  this.preprocess = opts.preprocess
31
31
 
32
+ //for points
33
+ /**
34
+ * @private
35
+ * @type {function(object,number):string} */
36
+ this.shape = opts.shape || ((f, z) => 'circle')
37
+ /**
38
+ * In pixel
39
+ * @private
40
+ * @type {function(object,number):number} */
41
+ this.size = opts.size || ((f, z) => 10)
42
+ /**
43
+ * @private
44
+ * @type {function(object,number):string} */
45
+ this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
46
+ /**
47
+ * @private
48
+ * @type {function(object,number):string} */
49
+ this.fillStyle = opts.fillStyle || ((f, z) => 'black')
50
+ /**
51
+ * In pixel
52
+ * @private
53
+ * @type {function(object,number):number} */
54
+ this.lineWidth = opts.lineWidth || ((f, z) => 2)
55
+
56
+
57
+
58
+ //for lines
59
+
32
60
  /**
33
61
  * @private
34
62
  * @type {function(object,number):string} */
35
63
  this.color = opts.color || ((f, z) => 'gray')
36
64
  /**
65
+ * In pixel
37
66
  * @private
38
67
  * @type {function(object,number):number} */
39
68
  this.width = opts.width || ((f, z) => 2)
@@ -42,6 +71,7 @@ export class GeoJSONLayer extends Layer {
42
71
  * @type {function(object,number):Array.<number>|undefined} */
43
72
  this.lineDash = opts.lineDash || ((f, z) => undefined)
44
73
 
74
+
45
75
  /**
46
76
  * @private
47
77
  * @type {Array.<object> | undefined} */
@@ -53,6 +83,7 @@ export class GeoJSONLayer extends Layer {
53
83
  this.loadingStatus = 'notLoaded'
54
84
  }
55
85
 
86
+
56
87
  /**
57
88
  * Draw the layer.
58
89
  * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
@@ -65,34 +96,73 @@ export class GeoJSONLayer extends Layer {
65
96
  return
66
97
  }
67
98
 
68
- //TODO sort lines by width ?
69
-
70
99
  //
71
100
  const z = geoCanvas.view.z
72
101
 
73
102
  for (const f of this.fs) {
74
- const cs = f.geometry.coordinates
75
- if (cs.length < 2) continue
76
-
77
- //set color
78
- const col = this.color(f, z)
79
- if (!col || col == 'none') continue
80
- geoCanvas.ctx.strokeStyle = col
81
-
82
- //set linewidth
83
- const wP = this.width(f, z)
84
- if (!wP || wP < 0) continue
85
- geoCanvas.ctx.lineWidth = wP * z
86
-
87
- //set line dash
88
- const ldP = this.lineDash(f, z)
89
- if (ldP) geoCanvas.ctx.setLineDash(ldP)
90
-
91
- //draw line
92
- geoCanvas.ctx.beginPath()
93
- geoCanvas.ctx.moveTo(cs[0][0], cs[0][1])
94
- for (let i = 1; i < cs.length; i++) geoCanvas.ctx.lineTo(cs[i][0], cs[i][1])
95
- geoCanvas.ctx.stroke()
103
+ const gt = f.geometry.type
104
+
105
+ if (gt == "Point") {
106
+ const c = f.geometry.coordinates
107
+
108
+ //get style parameters for the point feature
109
+ const shape = this.shape(f,z)
110
+ if(!shape || shape=="none") continue
111
+ const size = this.size(f,z) * z
112
+ if(!size) continue
113
+ const strokeStyle = this.strokeStyle(f,z)
114
+ const fillStyle = this.fillStyle(f,z)
115
+ const lineWidth = this.lineWidth(f,z) * z
116
+
117
+ //set canvas drawing parameters
118
+ if(strokeStyle) geoCanvas.ctx.strokeStyle = strokeStyle
119
+ if(fillStyle) geoCanvas.ctx.fillStyle = fillStyle
120
+ if(lineWidth) geoCanvas.ctx.lineWidth = lineWidth
121
+
122
+ if (shape == "circle") {
123
+ //draw circle - fill and stroke
124
+ geoCanvas.ctx.beginPath()
125
+ geoCanvas.ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
126
+ if(fillStyle) geoCanvas.ctx.fill()
127
+ if(strokeStyle && lineWidth) geoCanvas.ctx.stroke()
128
+ } else if (shape == "square") {
129
+ //draw square - fill and stroke
130
+ geoCanvas.ctx.beginPath()
131
+ geoCanvas.ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
132
+ if(fillStyle) geoCanvas.ctx.fill()
133
+ if(strokeStyle && lineWidth) geoCanvas.ctx.stroke()
134
+ } else {
135
+ console.error("Unexpected shape for point geojson: " + shape)
136
+ }
137
+
138
+ } else if (gt == "LineString") {
139
+
140
+ const cs = f.geometry.coordinates
141
+ if (cs.length < 2) continue
142
+
143
+ //set color
144
+ const col = this.color(f, z)
145
+ if (!col || col == 'none') continue
146
+ geoCanvas.ctx.strokeStyle = col
147
+
148
+ //set linewidth
149
+ const wP = this.width(f, z)
150
+ if (!wP || wP < 0) continue
151
+ geoCanvas.ctx.lineWidth = wP * z
152
+
153
+ //set line dash
154
+ const ldP = this.lineDash(f, z)
155
+ if (ldP) geoCanvas.ctx.setLineDash(ldP)
156
+
157
+ //draw line
158
+ geoCanvas.ctx.beginPath()
159
+ geoCanvas.ctx.moveTo(cs[0][0], cs[0][1])
160
+ for (let i = 1; i < cs.length; i++) geoCanvas.ctx.lineTo(cs[i][0], cs[i][1])
161
+ geoCanvas.ctx.stroke()
162
+ } else {
163
+ console.log("Unsupported geometry type in GeoJSONLayer: " + gt)
164
+ }
165
+
96
166
  }
97
167
 
98
168
  //...
@@ -1,7 +1,9 @@
1
1
  //@ts-check
2
2
  'use strict'
3
3
 
4
+ import { map } from 'd3-array'
4
5
  import { Style } from '../core/Style.js'
6
+ import { loadImage } from '../utils/utils.js'
5
7
 
6
8
  /**
7
9
  * @module style
@@ -14,17 +16,19 @@ export class ImageStyle extends Style {
14
16
  super(opts)
15
17
  opts = opts || {}
16
18
 
17
- /** A function returning the image code of a cell.
19
+ /** A function returning the image URL of a cell.
18
20
  * @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
19
- this.imageCode = opts.imageCode || (() => '') //(c,r,z,vs) => {}
20
-
21
- /** The dictionnary code -> image
22
- * @type {object} */
23
- this.images = opts.images || {}
21
+ this.image = opts.image || (() => '') //(c,r,z,vs) => {}
24
22
 
25
23
  /** The image size in ground meters
26
24
  * @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
27
25
  this.size = opts.size || ((cell, resolution) => resolution)
26
+
27
+ /** Dictionnary of preloaded images. url -> image
28
+ * @private
29
+ * @type {object} */
30
+ this.cache = {}
31
+
28
32
  }
29
33
 
30
34
  /**
@@ -33,7 +37,7 @@ export class ImageStyle extends Style {
33
37
  * @param {number} resolution
34
38
  * @override
35
39
  */
36
- draw(cells, geoCanvas, resolution) {
40
+ async draw(cells, geoCanvas, resolution) {
37
41
 
38
42
  //
39
43
  const z = geoCanvas.view.z,
@@ -48,28 +52,47 @@ export class ImageStyle extends Style {
48
52
  //
49
53
  for (let cell of cells) {
50
54
 
51
- //get cell image code
52
- const code = this.imageCode(cell, resolution, z, viewScale)
53
-
54
- //get image
55
- const image = this.images[code]
56
- if (!image) continue
55
+ //get cell image url
56
+ const url = this.image(cell, resolution, z, viewScale)
57
+ if (!url) continue
57
58
 
58
59
  //size and position values
59
60
  let sizePix = this.size(cell, resolution, z, viewScale) / z
60
61
  if (!sizePix) continue
61
- const d = (resolutionPix - sizePix) / 2
62
-
63
- try {
64
- geoCanvas.ctx.drawImage(image, geoCanvas.geoToPixX(cell.x) + d, geoCanvas.geoToPixY(cell.y) + d -resolutionPix, sizePix, sizePix)
65
-
66
- /*/red color filter
67
- geoCanvas.ctx.globalCompositeOperation = 'source-in';
68
- geoCanvas.ctx.fillStyle = 'red';
69
- geoCanvas.ctx.fillRect(geoCanvas.geoToPixX(cell.x) + d, geoCanvas.geoToPixY(cell.y) + d, sizePix, sizePix);
70
- geoCanvas.ctx.globalCompositeOperation = 'source-over';*/
71
- } catch (error) {
72
- console.error(error)
62
+
63
+ //get image from cache
64
+ const image = this.cache[url]
65
+
66
+ //loading, keep waiting
67
+ if (image == "loading") return;
68
+
69
+ //no image: load it
70
+ else if (!image) {
71
+ //tag as loading
72
+ this.cache[url] = "loading"
73
+
74
+ //define image
75
+ const img = new Image()
76
+ img.onload = () => {
77
+ //store image data in cache and redraw
78
+ this.cache[url] = img
79
+ geoCanvas.redraw()
80
+ }
81
+ img.onerror = () => {
82
+ //case when no image
83
+ console.warn("Could not retrieve image from", url)
84
+ }
85
+ //set URL to launch the download
86
+ img.src = url
87
+
88
+ } else {
89
+ //draw image
90
+ const d = (resolutionPix - sizePix) / 2
91
+ try {
92
+ geoCanvas.ctx.drawImage(image, geoCanvas.geoToPixX(cell.x) + d, geoCanvas.geoToPixY(cell.y) + d - resolutionPix, sizePix, sizePix)
93
+ } catch (error) {
94
+ console.error(error)
95
+ }
73
96
  }
74
97
 
75
98
  }