diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index b58b603..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -# Editor-based HTTP Client requests -/httpRequests/ diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..fc9d0dc --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + { + "customColor": "", + "associatedIndex": 1 +} + + + + + + + + + + + + + + + + + + + + + + + + + 1748031753881 + + + + + + + + + \ No newline at end of file diff --git a/.idea/wxbox.iml b/.idea/wxbox.iml index 9261e8c..0d676e3 100644 --- a/.idea/wxbox.iml +++ b/.idea/wxbox.iml @@ -1,36 +1,21 @@ - + - - - - - - - - - - - - - - - - - + + - + - - - + + + diff --git a/client/src/lib/Map.svelte b/client/src/lib/Map.svelte index bfcea72..5999431 100644 --- a/client/src/lib/Map.svelte +++ b/client/src/lib/Map.svelte @@ -11,6 +11,9 @@ import {borderLUT, fillLUT} from "$lib/alertLayer"; import AlertPopup from "$lib/AlertPopup.svelte"; import {CifContainer} from "$lib/generated_interop/cifContainer"; + import fragmentSource from "$lib/map/fragment.glsl?raw"; + import vertexSource from "$lib/map/vertex.glsl?raw"; + import {degreesToRadians} from "@turf/turf"; interface Props { categories: LayerList; @@ -143,12 +146,104 @@ map.getCanvas().style.cursor = ''; popup.remove(); }); - (async () => { - let r = await fetch('http://localhost:3000/v2/nexrad/l2/KM/1/REF'); - const bytes = await r.bytes(); - const container = CifContainer.fromBinary(bytes); - console.log('wxrad http://localhost:3000/v2/nexrad/l2/KRLX/1/REF: ', container); - })(); + + let r = await fetch('http://localhost:3000/v2/nexrad/l2/KFSD/1/REF'); + const buf = await r.arrayBuffer(); + + const container = CifContainer.fromBinary(new Uint8Array(buf)); + console.log('wxrad http://localhost:3000/v2/nexrad/l2/KFSD/1/REF: ', container); + + + const dataLayer = { + id: 'dataGl', + type: 'custom', + onAdd(map, gl) { + const vertexShader = gl.createShader(gl.VERTEX_SHADER); + gl.shaderSource(vertexShader, vertexSource); + gl.compileShader(vertexShader); + + const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); + gl.shaderSource(fragmentShader, fragmentSource); + gl.compileShader(fragmentShader); + + this.program = gl.createProgram(); + gl.attachShader(this.program, vertexShader); + gl.attachShader(this.program, fragmentShader); + gl.linkProgram(this.program); + + this.aPos = gl.getAttribLocation(this.program, 'a_pos'); + + /* + 110.574 km = 1 deg + deg = 1/110.574 km + + 111.320 * cos(latitude) km = 1 deg + + */ + const lat = 43.58777778; + const long = -96.72944444; + + const radar_range_maximum = 560; // ish km + const degrees_of_lat = radar_range_maximum / 110.574; + const degrees_of_long = radar_range_maximum / (111.320 * Math.cos(degreesToRadians(lat))); + + // A-C + // B-D + const a = maplibregl.MercatorCoordinate.fromLngLat({ + lng: long - degrees_of_long, + lat: lat + degrees_of_lat + }); + const b = maplibregl.MercatorCoordinate.fromLngLat({ + lng: long - degrees_of_long, + lat: lat - degrees_of_lat + }); + const c = maplibregl.MercatorCoordinate.fromLngLat({ + lng: long + degrees_of_long, + lat: lat + degrees_of_lat + }); + const d = maplibregl.MercatorCoordinate.fromLngLat({ + lng: long + degrees_of_long, + lat: lat - degrees_of_lat + }); + + + this.buffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([ + a.x, + a.y, + b.x, + b.y, + c.x, + c.y, + b.x, + b.y, + d.x, + d.y, + c.x, + c.y, + ]), + gl.STATIC_DRAW + ); + }, + render(gl, args) { + gl.useProgram(this.program); + gl.uniformMatrix4fv( + gl.getUniformLocation(this.program, 'u_matrix'), + false, + args.defaultProjectionData.mainMatrix + ); + gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); + gl.enableVertexAttribArray(this.aPos); + gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 0, 0); + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.drawArrays(gl.TRIANGLES, 0, 6); + } + } + map.addLayer(dataLayer); }); map.on('error', (e) => { console.error(e); diff --git a/client/src/lib/map/fragment.glsl b/client/src/lib/map/fragment.glsl new file mode 100644 index 0000000..87e1f46 --- /dev/null +++ b/client/src/lib/map/fragment.glsl @@ -0,0 +1,92 @@ +#version 300 es + +precision highp float; + +#define PI 3.141592653589793238462643 + +out highp vec4 fragColor; +uniform mat4 u_matrix; + +void xyToLngLat(in float x, in float y, out float lat, out float lng) { + lng = x * 360.0 - 180.0; + float y2 = 180.0 - y * 360.0; + lat = 360.0 / PI * atan(exp(y2 * PI / 180.0)) - 90.0; +} + +in vec4 raw_pos; + +#define a 6378137.0 +#define f 1.0 / 298.257223563 +#define b 6356752.314245 + +bool vincenty(in float phi1, in float phi2, in float l1, in float l2, out float a1, out float a2, out float s) { + float u1 = atan((1.0 - f) * tan(phi1)); + float u2 = atan((1.0 - f) * tan(phi2)); + float L = l2 - l1; + + float lambda = L; + + float sinSigma; + float cosSigma; + float sigma; + float sinAlpha; + float cosSquaredAlpha; + float cos2OmegaM; + float C; + + // sometimes fails to converge. set maximum iteration count + int iterCount = 0; + + while (lambda > pow(10.0, -12.0)) { + iterCount++; + if (iterCount > 10) { + return false; + } + sinSigma = sqrt(pow(cos(u2)*sin(lambda), 2.0) + pow(cos(u1)*sin(u2)-sin(u1)*cos(u2)*cos(lambda),2.0)); + cosSigma = sin(u1)*sin(u2)+cos(u1)*cos(u2)*cos(lambda); + sigma = atan(sinSigma,cosSigma); + + sinAlpha = (cos(u1)*cos(u2)*sin(lambda))/(sinSigma); + cosSquaredAlpha = 1.0 - pow(sinAlpha, 2.0); + cos2OmegaM = cosSigma - (2.0*sin(u1)*sin(u2))/(cosSquaredAlpha); + C = f/16.0 * cosSquaredAlpha * (4.0 + f * (4.0 - 3.0 * cosSquaredAlpha)); + lambda = L + (1.0 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2OmegaM + C*cosSigma * (-1.0 + 2.0 * pow(cos2OmegaM, 2.0)))); + } + + float uSquared = cosSquaredAlpha * ((pow(a, 2.0) - pow(b, 2.0))/pow(b, 2.0)); + float A = 1.0 + uSquared/16384.0 * (4096.0 + uSquared * (-768.0 + uSquared * (320.0 - 175.0*uSquared))); + float B = uSquared / 1024.0 * (256.0 + uSquared * (-128.0 + uSquared * (74.0 - 47.0*uSquared))); + + float deltaSigma = B * sinSigma * (cos2OmegaM + 1.0/4.0*B * (cosSigma * (-1.0 + 2.0*pow(cos2OmegaM,2.0)) - 1.0/6.0*B*cos2OmegaM*(-3.0+4.0*pow(sinSigma,2.0))*(-3.0+4.0*pow(cos2OmegaM,2.0)))); + s = b*A*(sigma - deltaSigma); + a1 = atan(cos(u2)*sin(lambda), cos(u1)*sin(u2)-sin(u1)*cos(u2)*cos(lambda)); + a2 = atan(cos(u1)*sin(lambda), -sin(u1)*cos(u2)+cos(u1)*sin(u2)*cos(lambda)); + + return true; +} + +void main() { + float lat; + float lng; + xyToLngLat(raw_pos.x, raw_pos.y, lat, lng); + + float radarLat = 43.58777778; + float radarLng = -96.72944444; + + float a1; + float a2; + float s; + ; + + // should be 43.58777778 + // 88 > x > 89 + // >40.0 + float delta = 0.01; + // + // abs(lat-43.5877)