Attempt to support .gpx files.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4389 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
2023-08-06 12:03:22 +00:00
parent e6fd33b969
commit 39927e75f2
2 changed files with 198 additions and 18 deletions

View File

@@ -1,6 +1,7 @@
import {LitElement, html, unsafeHTML, css, guard, until} from './lit-all.min.js';
import * as tfrpc from '/static/tfrpc.js';
import * as polyline from './polyline.js';
import {gpx_parse} from './gpx.js';
const k_client_id = '28276';
const k_redirect_url = 'https://tildefriends.net/~cory/gg/login';
@@ -75,7 +76,12 @@ class GgAppElement extends LitElement {
`, []);
for (let [index, row] of blob_ids.entries()) {
this.status = {text: 'loading activity data', value: index, max: blob_ids.length};
this.loaded_activities.push(JSON.parse(await tfrpc.rpc.get_blob(row.blob_id)));
let blob = await tfrpc.rpc.get_blob(row.blob_id);
try {
this.loaded_activities.push(JSON.parse(blob));
} catch {
this.loaded_activities.push(gpx_parse(blob));
}
}
this.status = undefined;
this.update_map();
@@ -208,6 +214,41 @@ class GgAppElement extends LitElement {
}
}
activity_bounds(activity) {
let min_lat = Number.MAX_VALUE;
let min_lon = Number.MAX_VALUE;
let max_lat = -Number.MAX_VALUE;
let max_lon = -Number.MAX_VALUE;
if (activity?.map?.polyline) {
for (let pt of polyline.decode(activity.map.polyline)) {
min_lat = Math.min(min_lat, pt[0]);
min_lon = Math.min(min_lon, pt[1]);
max_lat = Math.max(max_lat, pt[0]);
max_lon = Math.max(max_lon, pt[1]);
}
}
if (activity?.segments) {
for (let segment of activity.segments) {
for (let pt of segment) {
min_lat = Math.min(min_lat, pt.lat);
min_lon = Math.min(min_lon, pt.lon);
max_lat = Math.max(max_lat, pt.lat);
max_lon = Math.max(max_lon, pt.lon);
}
}
}
return {
min: {
lat: min_lat,
lng: min_lon,
},
max: {
lat: max_lat,
lng: max_lon,
},
};
}
async update_map() {
if (!this.leaflet) {
this.leaflet = L.map('map', {attributionControl: false, maxZoom: 16, bounceAtZoomLimits: false});
@@ -257,12 +298,11 @@ class GgAppElement extends LitElement {
this.grid_layer.addTo(this.leaflet);
}
for (let activity of this.loaded_activities) {
for (let pt of polyline.decode(activity.map.polyline)) {
this.min_lat = Math.min(this.min_lat, pt[0]);
this.min_lon = Math.min(this.min_lon, pt[1]);
this.max_lat = Math.max(this.max_lat, pt[0]);
this.max_lon = Math.max(this.max_lon, pt[1]);
}
let bounds = this.activity_bounds(activity);
this.min_lat = Math.min(this.min_lat, bounds.min.lat);
this.min_lon = Math.min(this.min_lon, bounds.min.lng);
this.max_lat = Math.max(this.max_lat, bounds.max.lat);
this.max_lon = Math.max(this.max_lon, bounds.max.lng);
}
this.leaflet.fitBounds([
[this.min_lat, this.min_lon],
@@ -392,17 +432,70 @@ class GgAppElement extends LitElement {
draw_activity_to_tile(image_data, width, height, ul, lr, activity) {
let color = this.activity_to_color(activity);
let last;
for (let pt of polyline.decode(activity.map.polyline)) {
let px = [
Math.floor(width * (pt[1] - ul.lng) / (lr.lng - ul.lng)),
Math.floor(height * (pt[0] - ul.lat) / (lr.lat - ul.lat)),
];
if (last) {
this.line(image_data, last[0], last[1], px[0], px[1], color);
if (activity?.map?.polyline) {
let last;
for (let pt of polyline.decode(activity.map.polyline)) {
let px = [
Math.floor(width * (pt[1] - ul.lng) / (lr.lng - ul.lng)),
Math.floor(height * (pt[0] - ul.lat) / (lr.lat - ul.lat)),
];
if (last) {
this.line(image_data, last[0], last[1], px[0], px[1], color);
}
last = px;
}
last = px;
}
if (activity?.segments) {
console.log('have a gpx');
for (let segment of activity.segments) {
let last;
for (let pt of segment) {
let px = [
Math.floor(width * (pt.lon - ul.lng) / (lr.lng - ul.lng)),
Math.floor(height * (pt.lat - ul.lat) / (lr.lat - ul.lat)),
];
if (last) {
this.line(image_data, last[0], last[1], px[0], px[1], color);
}
last = px;
}
}
}
}
async on_upload(event) {
let file = event.srcElement.files[0];
let xml = await file.text();
let gpx = gpx_parse(xml);
let blob_id = await tfrpc.rpc.store_blob(xml);
console.log('blob_id = ', blob_id);
let message = {
type: 'gg-activity',
mentions: [
{
link: `https://${gpx.link}/activity/${gpx.time}`,
name: 'activity_url',
},
{
link: blob_id,
name: 'activity_data',
}
],
};
console.log('message = ', message);
try {
let id = await tfrpc.rpc.appendMessage(this.id, message);
console.log('appended message', id);
} catch (e) {
console.log('augh', e);
}
}
upload() {
let input = document.createElement('input');
input.type = 'file';
input.onchange = this.on_upload;
input.click();
}
render() {
@@ -415,8 +508,14 @@ class GgAppElement extends LitElement {
}
return html`
<h1>Welcome, ${this.user.credentials.session.name} <span style="font-size: xx-small">${this.id}</span></h1>
<h3>${this.status?.text} <progress ?hidden=${!this.status?.max} value=${this.status?.value} max=${this.status?.max}>${this.status?.value}</progress></h3>
<div>
<h1>
Welcome, ${this.user.credentials.session.name}
<span style="font-size: xx-small">${this.id}</span>
<input type="button" value="📁" @click=${this.upload}></input>
</h1>
<h3>${this.status?.text} <progress ?hidden=${!this.status?.max} value=${this.status?.value} max=${this.status?.max}>${this.status?.value}</progress></h3>
</div>
`;
}
}