Skip to content

Commit

Permalink
Trying to workout handling IRL coords
Browse files Browse the repository at this point in the history
Using google's web mercator projection as x/y values. TBD if this will
stick.
  • Loading branch information
mayfield committed Apr 22, 2024
1 parent 16307cf commit 00dd79f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 37 deletions.
18 changes: 18 additions & 0 deletions src/env.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ export const worldMetas = {
altitudeOffsetHack: 0,
physicsSlopeScale: 100,
waterPlaneLevel: 0,
anchorX: 500, // XXX
anchorY: 500, // XXX
minX: -1000, // XXX
minY: -1000, // XXX
maxX: 1000, // XXX
maxY: 1000, // XXX
tileScale: 1, // XXX
mapScale: 4096, // XXX
}
};
try {
Expand Down Expand Up @@ -205,3 +213,13 @@ export function getRoutes(courseId) {
return routes;
}
rpc.register(getRoutes);


export function webMercatorProjection([lat, lng]) {
let siny = Math.sin((lat * Math.PI) / 180);
siny = Math.min(Math.max(siny, -0.9999), 0.9999);
return [
0.5 + lng / 360,
0.5 - Math.log((1 + siny) / (1 - siny)) / (4 * Math.PI),
];
}
71 changes: 34 additions & 37 deletions src/stats.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -676,20 +676,15 @@ export class StatsProcessor extends events.EventEmitter {
}

emulatePlayerStateFromRecord(record, extra) {
const courseId = env.realWorldCourseId;
const worldMeta = env.worldMetas[courseId];
let x = 0, y = 0, z = 0;
if (record.latlng) {
const [lat, lng] = record.latlng;
x = (lng - worldMeta.lonOffset) * worldMeta.lonDegDist * 100;
y = -(lat - worldMeta.latOffset) * worldMeta.latDegDist * 100;
[x, y] = env.webMercatorProjection(record.latlng);
}
if (record.altitude != null) {
z = (record.altitude - worldMeta.altitudeOffsetHack) / worldMeta.physicsSlopeScale * 100 -
worldMeta.waterPlaneLevel;
z = record.altitude;
}
return {
courseId,
courseId: env.realWorldCourseId,
worldTime: worldTimer.fromLocalTime(record.time * 1000),
power: record.power,
cadence: record.cadence,
Expand Down Expand Up @@ -739,47 +734,49 @@ export class StatsProcessor extends events.EventEmitter {
};
}

async _initGmapSession(key) {
// https://developers.google.com/maps/documentation/tile/session_tokens
const resp = await fetch(`https://tile.googleapis.com/v1/createSession?key=${key}`, {
method: 'POST',
headers: {'content-type': 'application/json'},
body: JSON.stringify({
mapType: 'roadmap', // roadmap, satellite, terrain, streetview
language: 'en-US',
region: 'US',
//imageFormat: 'png', // png, jpeg
//scale: 'scaleFactor1x', // 1x, 2x, 4x
//highDpi: false, // set to true with scaleFactor2x or 4x only
}),
});
if (!resp.ok) {
console.error("Failed to create google map API session:", resp.status, await resp.text());
throw new Error("Map Session Error");
}
return await resp.json();
}

async getIRLMapTile(x, y, z) {
const sig = [x,y,z].join();
if (this._gmapTileCache.has(sig)) {
return this._gmapTileCache.get(sig);
return await this._gmapTileCache.get(sig);
}
const key = this._googleMapTileKey;
if (!key) {
throw new Error("google map tile key required");
}
if (!this._gmapSession) {
// https://developers.google.com/maps/documentation/tile/session_tokens
const resp = await fetch(`https://tile.googleapis.com/v1/createSession?key=${key}`, {
method: 'POST',
headers: {'content-type': 'application/json'},
body: JSON.stringify({
mapType: 'roadmap', // roadmap, satellite, terrain, streetview
language: 'en-US',
region: 'US',
//imageFormat: 'png', // png, jpeg
//scale: 'scaleFactor1x', // 1x, 2x, 4x
//highDpi: false, // set to true with scaleFactor2x or 4x only
}),
});
if (!resp.ok) {
console.error("Failed to create google map API session:", resp.status, await resp.text());
throw new Error("Map Session Error");
}
this._gmapSession = await resp.json();
if (!this._gmapSessionPromise) {
this._gmapSessionPromise = this._initGmapSession(key);
}
const q = new URLSearchParams({
session: this._gmapSession.session,
key,
orientation: 0
});
const session = await this._gmapSessionPromise;
const q = new URLSearchParams({session: session.session, key});
// https://developers.google.com/maps/documentation/tile/roadmap
// z = 0 to 22
// [0, 0] = top left / north west
console.log(x, y, z);
const resp = await fetch(`https://tile.googleapis.com/v1/2dtiles/${z}/${x}/${y}?${q}`);
if (!resp.ok) {
console.error("Failed to get google map tile:", resp.status, await resp.text());
throw new Error("Map Tile Error");
const msg = await resp.text();
const e = new Error(`Map Tile Error [${resp.status}]: ` + msg);
this._gmapTileCache.set(sig, Promise.reject(e));
throw e;
}
const entry = {
contentType: resp.headers.get('content-type'),
Expand Down

0 comments on commit 00dd79f

Please sign in to comment.