-
Notifications
You must be signed in to change notification settings - Fork 5
/
viz.html
359 lines (323 loc) · 12.5 KB
/
viz.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
<html>
<head>
<script type="text/javascript" src="js/glutil2d.js"></script>
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="js/jquery.mousewheel.js"></script>
<script>
console.log("Loading wells.js...");
before_load = new Date();
</script>
<script src="wells.js"></script>
<script>
console.log("Loaded " + wells.length + " wells in " + (new Date() - before_load) / 1e3 + " seconds.");
MercatorProjection = function(west, north, east, south, width, height) {
var yScale = 1;
var yOrigin = 0;
function rawProjectLat(lat) {
return Math.log((1+Math.sin(lat*Math.PI/180))/Math.cos(lat*Math.PI/180));
}
function rawUnprojectLat(y) {
return (2 * Math.atan(Math.exp(y)) - Math.PI / 2) * 180 / Math.PI;
}
function interpolate(x, fromLow, fromHigh, toLow, toHigh) {
return (x - fromLow) / (fromHigh - fromLow) * (toHigh - toLow) + toLow;
}
this.latlngToPoint = function(latlng) {
var x = interpolate(latlng.lng, west, east, 0, width);
var y = interpolate(rawProjectLat(latlng.lat), rawProjectLat(north), rawProjectLat(south), 0, height);
return {"x":x, "y":y};
}
this.pointToLatlng = function(point) {
var lng = interpolate(point.x, 0, width, west, east);
var lat = rawUnprojectLat(interpolate(point.y, 0, height, rawProjectLat(north), rawProjectLat(south)));
return {"lat":lat, "lng":lng};
}
}
before_project = new Date();
console.log("Projecting into mercator...");
var projection = new MercatorProjection(-180, 85.05112877980659, 180, -85.05112877980659, 1335834, 1335834);
for (var i = 0; i < wells.length; i++) {
var loc = projection.latlngToPoint( {"lat": wells[i].Lat, "lng": wells[i].Lon} );
wells[i].x = (loc.x - 250000) / 100;
wells[i].y = (loc.y - 470000) / 100;
}
console.log("Projected wells in " + (new Date() - before_project) / 1e3 + " seconds.");
</script>
<!-- Include shader source as script elements with a type that
will cause the browser to ignore the script. (This follows
examples on learningwebgl.com.) The content of the shader
scipts is extracted using a function getElementText()
that is defined in glutil2d.js. -->
<script type="x-shader/x-vertex" id="vshader">
attribute vec2 vertexCoords;
uniform mat3 coordinateTransform;
uniform float pointSize;
void main() {
vec3 transformedCoords = coordinateTransform * vec3(vertexCoords, 1.0);
gl_Position = vec4(transformedCoords.xy, 0.0, 1.0);
gl_PointSize = pointSize;
}
</script>
<script type="x-shader/x-fragment" id="fshader">
precision mediump float;
uniform bool antialiased;
uniform sampler2D sampler;
uniform vec4 color;
void main() {
float dist = distance( gl_PointCoord, vec2(0.5) );
if (!antialiased) {
if (dist > 0.5)
discard;
gl_FragColor =texture2D(sampler,gl_PointCoord);
}
else {
float alpha = 1.0 - smoothstep(0.45,0.5,dist);
gl_FragColor = texture2D(sampler,gl_PointCoord);
gl_FragColor.a = alpha;
}
}
</script>
<script type="text/javascript">
"use strict";
var gl; // The webgl context, to be initialized in init().
var prog; // Identifies the webgl program.
var vertexAttributeBuffer; // Identifies the databuffer where vertex coords are stored.
var vertexAttributeLocation; // Identifies the vertex attribute variable in the shader program.
var pointSizeUniformLocation; // Identifies the uniform that controls the size of points.
var antialiasedLoc; // Identifies the uniform that determines whether points are antialiased.
var transformUniformLocation; // Identifies the coordinate matrix uniform variable.
var samplerLocation;
var pointRadius; // The radius of the points; half the point size. This is the min of 16 and half the maximum point size.
var pointCt = 100000; // The number of points to drawn.
//var points = new Float32Array(2*pointCt); // The coordinates of the points, which change from frame to frame.
var points;
//var velocities = new Float32Array(2*pointCt); // The velocities of the points, which determine how far they move in each frame.
/**
* Draw a rectangle, with object texture coords that will map the entire texture onto
* the rectangle (assuming that object texture coordinates are used).
*/
var seq = 0;
function draw() {
seq = seq + 0.5;
if (seq >150) seq = 0;
var pct = seq / 100;
if (pct < 0) pct = 0;
if (pct > 1) pct = 1;
gl.clearColor(0,0,0,0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindBuffer(gl.ARRAY_BUFFER,vertexAttributeBuffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.DYNAMIC_DRAW);
gl.vertexAttribPointer(vertexAttributeLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vertexAttributeLocation);
gl.drawArrays(gl.POINTS, 0, Math.floor(wells.length * 2 * pct));
//console.log("drew " + Math.floor(wells.length * pct) + " points");
}
/**
* Called by init to create the points and their velocities. The velocities
* detrmine how fast the points move during the animation. (Since the corrdinate
* system that is used is standard pixel coordinates, the unit of measure is
* pixels, and the velocity is given in pixels per second.)
*/
function createPointsOld() {
var width = gl.canvas.width;
var height = gl.canvas.height;
for (var i = 0; i < pointCt; i++) {
points[2*i] = pointRadius + Math.random()*(width-2*pointRadius);
points[2*i+1] = pointRadius + Math.random()*(height-2*pointRadius);
velocities[2*i] = 30+120*Math.random();
if (Math.random() < 0.5)
velocities[2*i] = - velocities[2*i];
velocities[2*i+1] = 30+120*Math.random();
if (Math.random() < 0.5)
velocities[2*i+1] = - velocities[2*i+1];
}
}
function createPoints() {
pointCt = wells.length;
points = new Float32Array(2*pointCt); // The coordinates of the points, which change from frame to frame.
for (var i = 0; i < wells.length; i++) {
points[2*i] = wells[i].x;
points[2*i+1] = wells[i].y;
}
console.log("Created " + wells.length + " points");
}
/**
* Applies a coordinate transformation to the webgl context by setting the value
* of the coordinateTransform uniform in the shader program. The canvas will display
* the region of the xy-plane with x ranging from xmin to xmax and y ranging from ymin
* to ymax. If ignoreAspect is true, these ranges will fill the canvas. If ignoreAspect
* is missing or is false, one of the x or y ranges will be expanded, if necessary,
* so that the aspect ratio is preserved.
*/
function coordinateTransform(xmin, xmax, ymin, ymax, ignoreAspect) {
if ( ! ignoreAspect) {
var displayAspect = gl.canvas.height / gl.canvas.width;
var requestedAspect = Math.abs((ymax-ymin)/(xmax-xmin));
if (displayAspect > requestedAspect) {
var excess= (ymax-ymin) * (displayAspect/requestedAspect - 1);
ymin -= excess/2;
ymax += excess/2;
}
else if (displayAspect < requestedAspect) {
var excess = (xmax-xmin) * (requestedAspect/displayAspect - 1);
xmin -= excess/2;
xmax += excess/2;
}
}
var coordTrans = [
2/(xmax-xmin), 0, 0,
0, 2/(ymax-ymin), 0,
-1 - 2*xmin/(xmax-xmin), -1 - 2*ymin/(ymax-ymin), 1
];
gl.uniformMatrix3fv( transformUniformLocation, false, coordTrans );
}
var animator;
var lastTime = 0; // Time of previous call to doFrame();
/**
* Do one frame of an animation, and call setTimeout to schedule the next
* frame. But don't do anything if animating is false. In each frame,
* each point's current velocity is added to its current position. If
* This puts the boundary of the ball of outside the canvas, then the
* velocity is modified to make the ball bounce off the wall.
*/
function doFrame(time) {
draw();
}
/**
* Called when user checks/unchecks the "Animating" checkbox.
* Responds by starting/stopping the animation.
*/
function doAnimate() {
//if (document.getElementById("animatecheckbox").checked) {
animator.start();
//}
//else {
// animator.stop();
//}
}
/**
* This function is called when the user changes the setting of a
* checkbox that controlls whether the fragment shader anti-aliases
* the boundary of the points that it draws.
*/
function doAntialias() {
var antialiased = 1;
gl.uniform1f(antialiasedLoc, antialiased);
if (!animator.isAnimating())
draw();
}
function loadTexture() {
var img = new Image();
img.onload = function() {
var id = gl.createTexture();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, id);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
if (!animator.isAnimating())
draw();
};
img.src = "orange.png";
}
var dragging = false;
var dragX, dragY;
function down(e) {
dragging = true;
console.log("down");
//console.log(e);
dragX = e.clientX;
dragY = e.clientY;
}
function move(e) {
if (dragging) {
console.log("move");
//console.log(e);
var deltaX = e.clientX - dragX;
var deltaY = e.clientY - dragY;
dragX = e.clientX;
dragY = e.clientY;
console.log("drag dx=" + deltaX + " dy=" + deltaY);
for (var i = 0; i < wells.length; i++) {
points[i * 2] += deltaX;
points[i * 2 + 1] += deltaY;
}
}
}
function up(e) {
dragging = false;
console.log("up");
//console.log(e);
}
function wheel(e, delta, dx, dy) {
var scale = Math.pow(1.001, dy);
console.log("wheel dy=" + dy + " | scale=" + scale);
console.log(e);
for (var i = 0; i < wells.length; i++) {
points[i * 2] = (points[i * 2] - e.offsetX) * scale + e.offsetX;
points[i * 2 + 1] = (points[i * 2 + 1] - e.offsetY) * scale + e.offsetY;
}
e.preventDefault();
e.stopPropagation();
}
/**
* Initializes the WebGL program including the relevant global variables
* and the WebGL state. Calls draw() to draw the picture for the first time.
*/
function init() {
//document.getElementById("animatecheckbox").checked = false; // (Required for reload in firefox.)
//document.getElementById("antialiascheckbox").checked = true;
try {
gl = createWebGLContext("glcanvas");
var vertexShaderSource = getElementText("vshader");
var fragmentShaderSource = getElementText("fshader");
prog = createProgram(gl,vertexShaderSource,fragmentShaderSource);
gl.useProgram(prog);
vertexAttributeLocation = gl.getAttribLocation(prog, "vertexCoords");
transformUniformLocation = gl.getUniformLocation(prog, "coordinateTransform");
pointSizeUniformLocation = gl.getUniformLocation(prog, "pointSize");
samplerLocation = gl.getUniformLocation(prog,"sampler");
antialiasedLoc = gl.getUniformLocation(prog, "antialiased");
gl.uniform1f(antialiasedLoc, 1);
gl.uniform1i(samplerLocation,0);
gl.activeTexture(gl.TEXTURE0);
coordinateTransform(0, gl.canvas.width, gl.canvas.height, 0); // Let's me use standard pixel coords.
vertexAttributeBuffer = gl.createBuffer();
var pointSizeRange = gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE);
pointRadius = Math.min(pointSizeRange[1]/2, 2);
gl.uniform1f(pointSizeUniformLocation, pointRadius * 2);
//gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA,
// gl.ZERO, gl.ONE );
gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
gl.enable(gl.BLEND);
createPoints();
animator = new Animator(doFrame);
loadTexture();
}
catch (e) {
alert("Could not initialize WebGL! " + e);
return;
}
draw();
doAnimate();
/// mouse events
$('#glcanvas').mousedown(down);
$('#glcanvas').mouseup(up);
$('#glcanvas').mousemove(move);
$('#glcanvas').bind('mousewheel', wheel);
// document.getElementById('
//if (myimage.addEventListener) {
// // IE9, Chrome, Safari, Opera
// myimage.addEventListener("mousewheel", MouseWheelHandler, false);
// // Firefox
// myimage.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
//}
}
$(init);
</script>
</head>
<body>
<canvas width="1920" height="1200" id="glcanvas" style="background-color:black; width: 100%; height: 100%"></canvas>
</body>
</html>