feat: vincenty's (maybe)
Some checks failed
Verify Latest Dependencies / Verify Latest Dependencies (push) Has been cancelled
build and test / wxbox - latest (push) Has been cancelled

This commit is contained in:
core 2025-05-23 16:55:23 -04:00
parent aa172be1ef
commit 7841a9ef2e
Signed by: core
GPG key ID: FDBF740DADDCEECF
8 changed files with 369 additions and 34 deletions

5
.idea/.gitignore generated vendored
View file

@ -1,5 +0,0 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/

2
.idea/vcs.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
<mapping directory="" vcs="Git" />
</component>
</project>

143
.idea/workspace.xml generated Normal file
View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="ALL" />
</component>
<component name="CargoProjects">
<cargoProject FILE="$PROJECT_DIR$/Cargo.toml" />
</component>
<component name="ChangeListManager">
<list default="true" id="2d855648-9644-469a-afa2-59beb52bb1d6" name="Changes" comment="feat: client work">
<change afterPath="$PROJECT_DIR$/client/src/lib/map/fragment.glsl" afterDir="false" />
<change afterPath="$PROJECT_DIR$/client/src/lib/map/vertex.glsl" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/wxbox.iml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/wxbox.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/client/src/lib/Map.svelte" beforeDir="false" afterPath="$PROJECT_DIR$/client/src/lib/Map.svelte" afterDir="false" />
<change beforePath="$PROJECT_DIR$/crates/tiler/config.toml" beforeDir="false" afterPath="$PROJECT_DIR$/crates/tiler/config.toml" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DarkyenusTimeTracker">
<option name="totalTimeSeconds" value="1475" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MacroExpansionManager">
<option name="directoryName" value="dds25bm7" />
</component>
<component name="ProjectColorInfo">{
&quot;customColor&quot;: &quot;&quot;,
&quot;associatedIndex&quot;: 1
}</component>
<component name="ProjectId" id="2xVmjnIcqq4NuCswlyfkC1ysvey" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
"git-widget-placeholder": "core/client-rewrite-again",
"node.js.detected.package.eslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"nodejs_package_manager_path": "npm",
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.first.attach.projects": "true",
"settings.editor.selected.configurable": "preferences.pluginManager",
"ts.external.directory.path": "/home/core/prj/personal/wxbox/client/node_modules/typescript/lib",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="RunManager">
<configuration name="Run wxbox-ar2" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package wxbox-ar2 --bin wxbox-ar2" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Run wxbox-tiler" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --package wxbox-tiler --bin wxbox-tiler" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
<configuration name="Test wxbox" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="test --workspace" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<option name="emulateTerminal" value="true" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="withSudo" value="false" />
<option name="buildTarget" value="REMOTE" />
<option name="backtrace" value="SHORT" />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>
<component name="RustProjectSettings">
<option name="toolchainHomeDirectory" value="$USER_HOME$/.cargo/bin" />
</component>
<component name="SharedIndexes">
<attachedChunks>
<set>
<option value="bundled-js-predefined-1d06a55b98c1-0b3e54e931b4-JavaScript-WS-241.18034.50" />
</set>
</attachedChunks>
</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="2d855648-9644-469a-afa2-59beb52bb1d6" name="Changes" comment="" />
<created>1748031753881</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1748031753881</updated>
<workItem from="1748031755784" duration="230000" />
<workItem from="1748031993681" duration="8000" />
<workItem from="1748032062973" duration="74000" />
<workItem from="1748032143420" duration="1307000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="VcsManagerConfiguration">
<MESSAGE value="feat: client work" />
<option name="LAST_COMMIT_MESSAGE" value="feat: client work" />
</component>
</project>

29
.idea/wxbox.iml generated
View file

@ -1,36 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<module type="EMPTY_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/wxbox-pal/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox-tiler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox-eccodes-sys/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox-web/wxbox-eccodes-sys/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox-grib2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_client_native/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_client_wasm/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/wxbox_web/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/grib2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/pal/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/tiler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/ar2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nommer/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/ar2/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/crates/ar2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/grib2/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/crates/tiler/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/crates/grib2/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/interchange/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nexrad-data/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nexrad-data/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nexrad-decode/examples" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nexrad-decode/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/nexrad-model/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
<sourceFolder url="file://$MODULE_DIR$/crates/nommer/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/pal/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/tiler/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />

View file

@ -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);

View file

@ -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) <delta && abs(lng+96.72944444)<delta
if (vincenty(radians(radarLat), radians(lat), radians(radarLng), radians(lng), a1, a2, s)) {
fragColor = vec4(0.0, 1.0, 0.0, 0.5);
} else {
fragColor = vec4(1.0, 0.0, 0.0, 0.5);
}
}

View file

@ -0,0 +1,13 @@
#version 300 es
precision highp float;
uniform mat4 u_matrix;
in vec2 a_pos;
out vec4 raw_pos;
void main() {
raw_pos = vec4(a_pos, 0.0, 1.0);
gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
}

View file

@ -26,3 +26,15 @@ Color4: 60 255 0 255 255 128 0 128 255
Color4: 70 255 255 255 255 128 128 128 255
Color4: 80 128 128 128 255
"""
[data.nexrad.l2]
palette = """
Color4: 10 164 164 255 0 100 100 192 255
Color4: 20 64 128 255 255 32 64 128 255
Color4: 30 0 255 0 255 0 128 0 255
Color4: 40 255 255 0 255 255 128 0 255
Color4: 50 255 0 0 255 160 0 0 255
Color4: 60 255 0 255 255 128 0 128 255
Color4: 70 255 255 255 255 128 128 128 255
Color4: 80 128 128 128 255
"""