dawn28 commited on
Commit
487c7aa
·
verified ·
1 Parent(s): 6c4b0a5

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +289 -19
index.html CHANGED
@@ -1,19 +1,289 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6
+ <title>GPS Dashboard Pro</title>
7
+
8
+ <style>
9
+ :root{
10
+ --bg:#0a0b0d;
11
+ --panel:#16181c;
12
+ --good:#00ff9d;
13
+ --mid:#ffaa00;
14
+ --bad:#ff4444;
15
+ }
16
+
17
+ body{
18
+ margin:0;
19
+ background:var(--bg);
20
+ color:#fff;
21
+ font-family:system-ui;
22
+ display:flex;
23
+ flex-direction:column;
24
+ height:100dvh;
25
+ }
26
+
27
+ /* MAIN SPEED */
28
+ .main{
29
+ flex:2;
30
+ display:flex;
31
+ flex-direction:column;
32
+ justify-content:center;
33
+ align-items:center;
34
+ }
35
+
36
+ #speed{
37
+ font-size:clamp(90px,30vw,180px);
38
+ font-weight:900;
39
+ margin:0;
40
+ letter-spacing:-2px;
41
+ }
42
+
43
+ .unit{
44
+ color:#777;
45
+ letter-spacing:6px;
46
+ }
47
+
48
+ /* STATUS BAR */
49
+ .status{
50
+ text-align:center;
51
+ padding:10px;
52
+ font-size:12px;
53
+ letter-spacing:2px;
54
+ background:rgba(255,255,255,0.05);
55
+ }
56
+
57
+ /* ADDRESS */
58
+ .address{
59
+ text-align:center;
60
+ padding:10px;
61
+ font-size:14px;
62
+ color:#ccc;
63
+ border-bottom:1px solid #222;
64
+ }
65
+
66
+ /* GRID */
67
+ .panel{
68
+ background:var(--panel);
69
+ padding:12px;
70
+ }
71
+
72
+ .grid{
73
+ display:grid;
74
+ grid-template-columns:repeat(3,1fr);
75
+ gap:12px;
76
+ font-size:11px;
77
+ }
78
+
79
+ .item{
80
+ text-align:center;
81
+ }
82
+
83
+ .label{
84
+ color:#666;
85
+ font-size:10px;
86
+ }
87
+
88
+ .value{
89
+ font-family:monospace;
90
+ font-size:13px;
91
+ }
92
+
93
+ </style>
94
+ </head>
95
+
96
+ <body>
97
+
98
+ <div class="main">
99
+ <p id="speed">0.0</p>
100
+ <p class="unit">KM/H</p>
101
+ </div>
102
+
103
+ <div id="status" class="status">INITIALIZING GPS...</div>
104
+
105
+ <div id="address" class="address">Detecting address...</div>
106
+
107
+ <div class="panel">
108
+ <div class="grid">
109
+ <div class="item"><div class="label">Heading</div><div id="head" class="value">---</div></div>
110
+ <div class="item"><div class="label">Accuracy</div><div id="acc" class="value">---</div></div>
111
+ <div class="item"><div class="label">Altitude</div><div id="alt" class="value">---</div></div>
112
+ <div class="item"><div class="label">Lat</div><div id="lat" class="value">---</div></div>
113
+ <div class="item"><div class="label">Lon</div><div id="lon" class="value">---</div></div>
114
+ <div class="item"><div class="label">Confidence</div><div id="conf" class="value">---</div></div>
115
+ </div>
116
+ </div>
117
+
118
+ <script>
119
+ // --- ELEMENTS ---
120
+ const speedEl = document.getElementById("speed");
121
+ const statusEl = document.getElementById("status");
122
+ const addressEl = document.getElementById("address");
123
+
124
+ const headEl = document.getElementById("head");
125
+ const accEl = document.getElementById("acc");
126
+ const altEl = document.getElementById("alt");
127
+ const latEl = document.getElementById("lat");
128
+ const lonEl = document.getElementById("lon");
129
+ const confEl = document.getElementById("conf");
130
+
131
+ // --- STATE ---
132
+ let state={
133
+ lastFix:null,
134
+ emaSpeed:null,
135
+ firstGood:false,
136
+ lastHeading:null,
137
+ lastGeoKey:"",
138
+ lastGeoTime:0
139
+ };
140
+
141
+ // --- HAVERSINE ---
142
+ function dist(a,b){
143
+ const R=6371000;
144
+ const toRad=x=>x*Math.PI/180;
145
+ const dLat=toRad(b[0]-a[0]);
146
+ const dLon=toRad(b[1]-a[1]);
147
+ const x=Math.sin(dLat/2)**2+
148
+ Math.cos(toRad(a[0]))*Math.cos(toRad(b[0]))*
149
+ Math.sin(dLon/2)**2;
150
+ return 2*R*Math.asin(Math.sqrt(x));
151
+ }
152
+
153
+ // --- SAFE DERIVED ---
154
+ function safeDerived(c,ts){
155
+ if(!state.lastFix) return null;
156
+ const dt=(ts-state.lastFix.ts)/1000;
157
+ if(dt<0.8||dt>5) return null;
158
+
159
+ const d=dist(
160
+ [state.lastFix.lat,state.lastFix.lon],
161
+ [c.latitude,c.longitude]
162
+ );
163
+
164
+ if(d<3) return 0;
165
+
166
+ const s=d/dt;
167
+ if(s>55) return null;
168
+
169
+ return s;
170
+ }
171
+
172
+ // --- BEST SPEED ---
173
+ function bestSpeed(c,ts){
174
+ if(c.speed && c.speed>0.5) return c.speed;
175
+ const d=safeDerived(c,ts);
176
+ return d ?? 0;
177
+ }
178
+
179
+ // --- SMOOTH ---
180
+ function smooth(v){
181
+ if(state.emaSpeed===null){
182
+ state.emaSpeed=v;
183
+ return v;
184
+ }
185
+ const a=v>state.emaSpeed?0.35:0.2;
186
+ state.emaSpeed=a*v+(1-a)*state.emaSpeed;
187
+ if(state.emaSpeed<0.2) state.emaSpeed=0;
188
+ return state.emaSpeed;
189
+ }
190
+
191
+ // --- HEADING ---
192
+ function stableHeading(h,s){
193
+ if(s<1.5) return state.lastHeading;
194
+ if(h==null) return state.lastHeading;
195
+
196
+ if(state.lastHeading==null){
197
+ state.lastHeading=h;
198
+ return h;
199
+ }
200
+
201
+ let diff=h-state.lastHeading;
202
+ if(diff>180) diff-=360;
203
+ if(diff<-180) diff+=360;
204
+
205
+ state.lastHeading+=diff*0.25;
206
+ return state.lastHeading;
207
+ }
208
+
209
+ function headingText(h){
210
+ if(h==null) return "---";
211
+ const d=['N','NE','E','SE','S','SW','W','NW'];
212
+ return d[Math.round(h/45)%8]+" "+Math.round(h)+"°";
213
+ }
214
+
215
+ // --- CONF ---
216
+ function conf(acc){
217
+ if(acc<=10) return ["HIGH","#00ff9d"];
218
+ if(acc<=30) return ["MED","#ffaa00"];
219
+ return ["LOW","#ff4444"];
220
+ }
221
+
222
+ // --- ADDRESS ---
223
+ async function updateAddress(lat,lon){
224
+ const key=lat.toFixed(3)+","+lon.toFixed(3);
225
+ const now=Date.now();
226
+
227
+ if(key===state.lastGeoKey) return;
228
+ if(now-state.lastGeoTime<20000) return;
229
+
230
+ state.lastGeoKey=key;
231
+ state.lastGeoTime=now;
232
+
233
+ try{
234
+ const r=await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}`);
235
+ const d=await r.json();
236
+ addressEl.textContent=d.display_name?.split(",").slice(0,3).join(",") || "Unknown";
237
+ }catch{}
238
+ }
239
+
240
+ // --- MAIN ---
241
+ navigator.geolocation.watchPosition((pos)=>{
242
+ const c=pos.coords;
243
+ const ts=Date.now();
244
+
245
+ let v=bestSpeed(c,ts);
246
+
247
+ let final;
248
+ if(!state.firstGood){
249
+ if(v>1.5 && v<40){
250
+ state.firstGood=true;
251
+ final=v;
252
+ }else final=0;
253
+ }else{
254
+ final=smooth(v);
255
+ }
256
+
257
+ const kmh=(final*3.6).toFixed(1);
258
+
259
+ const [label,color]=conf(c.accuracy);
260
+
261
+ speedEl.textContent=kmh;
262
+ speedEl.style.color=color;
263
+
264
+ statusEl.textContent=`CONFIDENCE: ${label}`;
265
+ statusEl.style.color=color;
266
+
267
+ accEl.textContent=Math.round(c.accuracy)+"m";
268
+ altEl.textContent=c.altitude!=null?Math.round(c.altitude)+"m":"N/A";
269
+ latEl.textContent=c.latitude.toFixed(4);
270
+ lonEl.textContent=c.longitude.toFixed(4);
271
+
272
+ const h=stableHeading(c.heading,kmh);
273
+ headEl.textContent=headingText(h);
274
+
275
+ confEl.textContent=label;
276
+
277
+ updateAddress(c.latitude,c.longitude);
278
+
279
+ state.lastFix={lat:c.latitude,lon:c.longitude,ts};
280
+
281
+ },()=>{},{
282
+ enableHighAccuracy:true,
283
+ maximumAge:5000,
284
+ timeout:10000
285
+ });
286
+ </script>
287
+
288
+ </body>
289
+ </html>