Restarting from scratch

This commit is contained in:
vdv committed 2022-10-17 10:08:00 +02:00
1 parent ed951208e8
commit a4bd11aab0
88 files changed
+1714 -17027

No files matched your search

-26
View File
@@ -1,26 +0,0 @@
import { createAnimation } from '@ionic/react';
export const enterAnimation = (baseEl: HTMLElement) => {
const root = baseEl.shadowRoot;
const backdropAnimation = createAnimation()
.addElement(root?.querySelector('ion-backdrop')!)
.fromTo('opacity', '0.01', 'var(--backdrop-opacity)');
const wrapperAnimation = createAnimation()
.addElement(root?.querySelector('.modal-wrapper')!)
.keyframes([
{ offset: 0, opacity: '0', transform: 'scale(0)' },
{ offset: 1, opacity: '0.99', transform: 'scale(1)' },
]);
return createAnimation()
.addElement(baseEl)
.easing('ease-out')
.duration(500)
.addAnimation([backdropAnimation, wrapperAnimation]);
};
export const leaveAnimation = (baseEl: HTMLElement) => {
return enterAnimation(baseEl).direction('reverse');
};
-96
View File
@@ -1,96 +0,0 @@
import { BackgroundGeolocationPlugin } from '@capacitor-community/background-geolocation';
import { registerPlugin } from '@capacitor/core';
const BackgroundGeolocation = registerPlugin<BackgroundGeolocationPlugin>(
'BackgroundGeolocation'
);
const backgroundGeolocationConfig = {
// If the "backgroundMessage" option is defined, the watcher will
// provide location updates whether the app is in the background or the
// foreground. If it is not defined, location updates are only
// guaranteed in the foreground. This is true on both platforms.
// On Android, a notification must be shown to continue receiving
// location updates in the background. This option specifies the text of
// that notification.
backgroundMessage: 'Cancel to prevent battery drain.',
// The title of the notification mentioned above. Defaults to "Using
// your location".
backgroundTitle: 'Tracking You.',
// Whether permissions should be requested from the user automatically,
// if they are not already granted. Defaults to "true".
requestPermissions: true,
// If "true", stale locations may be delivered while the device
// obtains a GPS fix. You are responsible for checking the "time"
// property. If "false", locations are guaranteed to be up to date.
// Defaults to "false".
stale: false,
// The minimum number of metres between subsequent locations. Defaults
// to 0.
distanceFilter: 10,
};
export const startBackgroundGeolocation = async (
newLocationHandler: any,
distanceFilter: number
) => {
backgroundGeolocationConfig.distanceFilter = distanceFilter;
const locationHandler = (location: any, error: any) => {
console.log('com.dyomedea.dyomedea LOG', ' - Callback');
if (error) {
if (error.code === 'NOT_AUTHORIZED') {
if (
window.confirm(
'This app needs your location, ' +
'but does not have permission.\n\n' +
'Open settings now?'
)
) {
// It can be useful to direct the user to their device's
// settings when location permissions have been denied. The
// plugin provides the 'openSettings' method to do exactly
// this.
BackgroundGeolocation.openSettings();
}
}
return console.error('com.dyomedea.dyomedea LOG', ' - error: ', error);
}
console.log(location);
if (location !== undefined) {
newLocationHandler(location);
}
return console.log('com.dyomedea.dyomedea LOG', ' - location: ', location);
};
var watcher_id;
console.log('com.dyomedea.dyomedea LOG', ' - Adding the watcher');
await BackgroundGeolocation.addWatcher(
backgroundGeolocationConfig,
locationHandler
)
.then(function after_the_watcher_has_been_added(id) {
// When a watcher is no longer needed, it should be removed by calling
// 'removeWatcher' with an object containing its ID.
console.log('com.dyomedea.dyomedea LOG', ' - Watcher added');
watcher_id = id;
/*BackgroundGeolocation.removeWatcher({
id: watcher_id,
}); */
})
.catch((reason) => {
console.error('com.dyomedea.dyomedea LOG', ' - reason: ', reason);
});
return watcher_id;
};
export const stopBackgroundGeolocation = (watcher_id: any) => {
BackgroundGeolocation.removeWatcher({
id: watcher_id,
});
};
-1
View File
@@ -1 +0,0 @@
declare module 'docuri';
-35
View File
@@ -1,35 +0,0 @@
export interface Point {
x: number;
y: number;
}
export interface geoPoint {
lon: number;
lat: number;
}
// cf https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#ECMAScript_(JavaScript/ActionScript,_etc.)
export const lon2tile = (lon: number, zoom: number) => {
return ((Number(lon) + 180) / 360) * Math.pow(2, zoom);
};
export const lat2tile = (lat: number, zoom: number) => {
return (
((1 -
Math.log(
Math.tan((Number(lat) * Math.PI) / 180) +
1 / Math.cos((Number(lat) * Math.PI) / 180)
) /
Math.PI) /
2) *
Math.pow(2, zoom)
);
};
export function tile2long(x: number, z: number) {
return (x / Math.pow(2, z)) * 360 - 180;
}
export function tile2lat(y: number, z: number) {
var n = Math.PI - (2 * Math.PI * y) / Math.pow(2, z);
return (180 / Math.PI) * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
}
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2017 Zheng-Xiang Ke
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-91
View File
@@ -1,91 +0,0 @@
# gpx-parser-builder
A simple gpx parser and builder between GPX string and JavaScript object. It is dependent on [isomorphic-xml2js](https://github.com/RikkiGibson/isomorphic-xml2js).
[![npm](https://img.shields.io/npm/dt/gpx-parser-builder.svg)](https://www.npmjs.com/package/gpx-parser-builder)
[![GitHub stars](https://img.shields.io/github/stars/kf99916/gpx-parser-builder.svg)](https://github.com/kf99916/gpx-parser-builder/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/kf99916/gpx-parser-builder.svg)](https://github.com/kf99916/gpx-parser-builder/network)
[![npm](https://img.shields.io/npm/v/gpx-parser-builder.svg)](https://www.npmjs.com/package/gpx-parser-builder)
[![GitHub license](https://img.shields.io/github/license/kf99916/gpx-parser-builder.svg)](https://github.com/kf99916/gpx-parser-builder/blob/master/LICENSE)
## Requirements
gpx-parser-builder is written with ECMAScript 6. You can leverage [Babel](https://babeljs.io/) and [Webpack](https://webpack.js.org/) to make all browsers available.
## Installation
```bash
npm install gpx-parser-builder --save
```
## Version
v1.0.0+ is a breaking change for v0.2.2-. v1.0.0+ fully supports gpx files including waypoints, routes, and tracks. Every gpx type is 1-1 corresponding to a JavaScript class.
## Usage
```javascript
import GPX from 'gpx-parser-builder';
// Parse gpx
const gpx = GPX.parse('GPX_STRING');
window.console.dir(gpx.metadata);
window.console.dir(gpx.wpt);
window.console.dir(gpx.trk);
// Build gpx
window.console.log(gpx.toString());
```
Get more details about usage with the unit tests.
### GPX
The GPX JavaScript object.
`constructor(object)`
```javascript
const gpx = new Gpx({$:{...}, metadat: {...}, wpt:[{...},{...}]}, trk: {...}, rte: {...})
```
#### Member Variables
`$` the attributes for the gpx element. Default value:
```javascript
{
'version': '1.1',
'creator': 'gpx-parser-builder',
'xmlns': 'http://www.topografix.com/GPX/1/1',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation': 'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'
}
```
`metadata` the metadata for the gpx.
`wpt` array of waypoints. It is corresponded to `<wpt>`. The type of all elements in `wpt` is `Waypoint`;
`rte` array of routes. It is corresponded to `<rte>`. The type of all elements in `rte` is `Route`;
`trk` array of tracks. It is corresponded to `<trk>`. The type of all elements in `trk` is `Track`;
#### Static Methods
`parse(gpxString)` parse gpx string to Gpx object. return `null` if parsing failed.
#### Member Methods
`toString(options)` GPX object to gpx string. The options is for [isomorphic-xml2js](https://github.com/RikkiGibson/isomorphic-xml2js).
## Save as GPX file in the frontend
You can leverage [StreamSaver.js](https://github.com/jimmywarting/StreamSaver.js) or [FileSaver.js](https://github.com/eligrey/FileSaver.js) to save as GPX file. ⚠️Not all borwsers support the above file techniques. ⚠️️️
## Author
Zheng-Xiang Ke, kf99916@gmail.com
## License
gpx-parser-builder is available under the MIT license. See the LICENSE file for more info.
-36
View File
@@ -1,36 +0,0 @@
{
"name": "gpx-parser-builder",
"version": "1.0.2",
"description": "A simple gpx parser and builder between GPX string and JavaScript object",
"main": "./src/gpx.js",
"scripts": {
"test": "mocha --require @babel/register test/**/*.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/kf99916/gpx-parser-builder.git"
},
"keywords": [
"gpx",
"parser",
"builder"
],
"author": "Zheng-Xiang Ke",
"license": "MIT",
"bugs": {
"url": "https://github.com/kf99916/gpx-parser-builder/issues"
},
"homepage": "https://github.com/kf99916/gpx-parser-builder",
"files": [
"src"
],
"devDependencies": {
"@babel/core": "~7.7",
"@babel/preset-env": "~7.7",
"@babel/register": "~7.7",
"mocha": "~6.2"
},
"dependencies": {
"isomorphic-xml2js": "~0.1"
}
}
-8
View File
@@ -1,8 +0,0 @@
export default class Bounds {
constructor(object) {
this.minlat = object.minlat;
this.minlon = object.minlon;
this.maxlat = object.maxlat;
this.maxlon = object.maxlon;
}
}
@@ -1,7 +0,0 @@
export default class Copyright {
constructor(object) {
this.author = object.author;
this.year = object.year;
this.license = object.license;
}
}
-13
View File
@@ -1,13 +0,0 @@
declare module 'gpx-parser-builder' {
class GPX {
static parse(gpxString: any): any;
constructor(object: any);
$: any;
extensions: any;
metadata: any;
wpt: any;
rte: any;
trk: any;
toString(options: any): string;
}
}
-79
View File
@@ -1,79 +0,0 @@
import * as xml2js from 'isomorphic-xml2js';
import Metadata from './metadata';
import Waypoint from './waypoint';
import Route from './route';
import Track from './track';
import {removeEmpty, allDatesToISOString} from './utils';
const defaultAttributes = {
version: '1.1',
creator: 'gpx-parser-builder',
xmlns: 'http://www.topografix.com/GPX/1/1',
'xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
'xsi:schemaLocation':
'http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'
}
export default class GPX {
constructor(object) {
this.$ = Object.assign({}, defaultAttributes, object.$ || object.attributes || {});
this.extensions = object.extensions;
if (object.metadata) {
this.metadata = new Metadata(object.metadata);
}
if (object.wpt) {
if (!Array.isArray(object.wpt)) {
object.wpt = [object.wpt];
}
this.wpt = object.wpt.map(wpt => new Waypoint(wpt));
}
if (object.rte) {
if (!Array.isArray(object.rte)) {
object.rte = [object.rte];
}
this.rte = object.rte.map(rte => new Route(rte));
}
if (object.trk) {
if (!Array.isArray(object.trk)) {
object.trk = [object.trk];
}
this.trk = object.trk.map(trk => new Track(trk));
}
removeEmpty(this);
}
static parse(gpxString) {
let gpx;
xml2js.parseString(gpxString, {
explicitArray: false
}, (err, xml) => {
if (err) {
return;
}
if (!xml.gpx) {
return;
}
gpx = new GPX({
attributes: xml.gpx.$,
metadata: xml.gpx.metadata,
wpt: xml.gpx.wpt,
rte: xml.gpx.rte,
trk: xml.gpx.trk
});
});
return gpx;
}
toString(options) {
options = options || {};
options.rootName = 'gpx';
const builder = new xml2js.Builder(options), gpx = new GPX(this);
allDatesToISOString(gpx);
return builder.buildObject(gpx);
}
}
-8
View File
@@ -1,8 +0,0 @@
export default class Link {
constructor(object) {
this.$ = {};
this.$.href = object.$.href || object.href;
this.text = object.text;
this.type = object.type;
}
}
@@ -1,29 +0,0 @@
import Copyright from './copyright';
import Link from './link';
import Person from './person';
import Bounds from './bounds';
export default class Metadata {
constructor(object) {
this.name = object.name;
this.desc = object.desc;
this.time = object.time ? new Date(object.time) : new Date();
this.keywords = object.keywords;
this.extensions = object.extensions;
if (object.author) {
this.author = new Person(object.author);
}
if (object.link) {
if (!Array.isArray(object.link)) {
object.link = [object.link];
}
this.link = object.link.map(l => new Link(l));
}
if (object.bounds) {
this.bounds = new Bounds(object.bounds);
}
if (object.copyright) {
this.copyright = new Copyright(object.copyright);
}
}
}
-11
View File
@@ -1,11 +0,0 @@
import Link from './link';
export default class Person {
constructor(object) {
this.name = object.name;
this.email = object.email;
if (object.link) {
this.link = new Link(object.link);
}
}
}
-27
View File
@@ -1,27 +0,0 @@
import Waypoint from './waypoint';
import Link from './link';
export default class Route {
constructor(object) {
this.name = object.name;
this.cmt = object.cmt;
this.desc = object.desc;
this.src = object.src;
this.number = object.number;
this.type = object.type;
this.extensions = object.extensions;
if (object.link) {
if (!Array.isArray(object.link)) {
this.link = [object.link];
}
this.link = object.link.map(l => new Link(l));
}
if (object.rtept) {
if (!Array.isArray(object.rtept)) {
this.rtept = [object.rtept];
}
this.rtept = object.rtept.map(pt => new Waypoint(pt));
}
}
}
@@ -1,13 +0,0 @@
import Waypoint from './waypoint';
export default class TrackSegment {
constructor(object) {
if (object.trkpt) {
if (!Array.isArray(object.trkpt)) {
object.trkpt = [object.trkpt];
}
this.trkpt = object.trkpt.map(pt => new Waypoint(pt));
}
this.extensions = object.extensions;
}
}
-26
View File
@@ -1,26 +0,0 @@
import TrackSegment from './track-segment';
import Link from './link';
export default class Track {
constructor(object) {
this.name = object.name;
this.cmt = object.cmt;
this.desc = object.desc;
this.src = object.src;
this.number = object.number;
this.type = object.type;
this.extensions = object.extensions;
if (object.link) {
if (!Array.isArray(object.link)) {
object.link = [object.link];
}
this.link = object.link.map(l => new Link(l));
}
if (object.trkseg) {
if (!Array.isArray(object.trkseg)) {
object.trkseg = [object.trkseg];
}
this.trkseg = object.trkseg.map(seg => new TrackSegment(seg));
}
}
}
-23
View File
@@ -1,23 +0,0 @@
function removeEmpty(obj) {
Object.entries(obj).forEach(([key, val]) => {
if (val && val instanceof Object) {
removeEmpty(val);
} else if (val == null) {
delete obj[key];
}
});
}
function allDatesToISOString(obj) {
Object.entries(obj).forEach(([key, val]) => {
if (val) {
if (val instanceof Date) {
obj[key] = val.toISOString().split('.')[0] + 'Z';
} else if (val instanceof Object) {
allDatesToISOString(val);
}
}
});
}
export { removeEmpty, allDatesToISOString };
@@ -1,32 +0,0 @@
import Link from './link';
export default class Waypoint {
constructor(object) {
this.$ = {};
this.$.lat = object.$.lat === 0 || object.lat === 0 ? 0 : object.$.lat || object.lat || -1;
this.$.lon = object.$.lon === 0 || object.lon === 0 ? 0 : object.$.lon || object.lon || -1;
this.ele = object.ele;
this.time = object.time ? new Date(object.time) : new Date();
this.magvar = object.magvar;
this.geoidheight = object.geoidheight;
this.name = object.name;
this.cmt = object.cmt;
this.desc = object.desc;
this.src = object.src;
this.sym = object.sym;
this.type = object.type;
this.sat = object.sat;
this.hdop = object.hdop;
this.vdop = object.vdop;
this.pdop = object.pdop;
this.ageofdgpsdata = object.ageofdgpsdata;
this.dgpsid = object.dgpsid;
this.extensions = object.extensions;
if (object.link) {
if (!Array.isArray(object.link)) {
object.link = [object.link];
}
this.link = object.link.map(l => new Link(l));
}
}
}
-116
View File
@@ -1,116 +0,0 @@
import { route } from 'docuri';
import uri from './ids';
describe('Checking some DocURI features', () => {
test(', basic route', () => {
const gpx = route('gpx/:id');
expect(gpx({ id: 10 })).toBe('gpx/10');
});
test(', basic route (vice-versa', () => {
const gpx = route('gpx/:id');
expect(gpx('gpx/10')).toMatchObject({ id: '10' });
});
});
describe('Checking a multilevel route', () => {
test(', using the two levels', () => {
const gpx = route('gpx/:gpx/trk/:trk');
expect(gpx({ gpx: 10, trk: 0 })).toBe('gpx/10/trk/0');
});
test(', using the two levels (vive-versa)', () => {
const gpx = route('gpx/:gpx/trk/:trk');
expect(gpx('gpx/10/trk/0')).toMatchObject({ gpx: '10', trk: '0' });
});
});
describe('Checking a multilevel route with optional part', () => {
test(', using the two levels', () => {
const gpx = route('gpx/:gpx(/trk/:trk)');
expect(gpx({ gpx: 10, trk: 0 })).toBe('gpx/10/trk/0');
});
test(', using the two levels (vive-versa)', () => {
const gpx = route('gpx/:gpx(/trk/:trk)');
expect(gpx('gpx/10/trk/0')).toMatchObject({ gpx: '10', trk: '0' });
});
test(', using only one level', () => {
const gpx = route('gpx/:gpx(/trk/:trk)');
expect(gpx({ gpx: 10 })).toBe('gpx/10/trk/'); //Unfortunately !
});
test(', using only one level (vive-versa)', () => {
const gpx = route('gpx/:gpx(/trk/:trk)');
expect(gpx('gpx/10')).toMatchObject({ gpx: '10' });
});
});
describe('Checking gpx ids', () => {
test(', vice', () => {
const gpx = uri('gpx', { gpx: 'id' });
expect(gpx).toBe('gpx/id');
});
test(', and versa', () => {
const gpx = uri('gpx', 'gpx/id');
expect(gpx).toMatchObject({ gpx: 'id' });
});
});
describe('Checking trk ids', () => {
test(', vice', () => {
const rte = uri('trk', { gpx: 'gpxid', trk: 'trkid' });
expect(rte).toBe('gpx/gpxid/trk/trkid');
});
test(', and versa', () => {
const rte = uri('trk', 'gpx/gpxid/trk/trkid');
expect(rte).toMatchObject({ gpx: 'gpxid', trk: 'trkid' });
});
});
describe('Checking trkseg ids', () => {
test(', vice', () => {
const rte = uri('trkseg', {
gpx: 'gpxid',
trk: 'trkid',
trkseg: 'trksegid',
});
expect(rte).toBe('gpx/gpxid/trk/trkid/trksegid');
});
test(', and versa', () => {
const rte = uri('trkseg', 'gpx/gpxid/trk/trkid/trksegid');
expect(rte).toMatchObject({
gpx: 'gpxid',
trk: 'trkid',
trkseg: 'trksegid',
});
});
});
describe('Checking trkpt ids', () => {
test(', vice', () => {
const rte = uri('trkpt', {
gpx: 'gpxid',
trk: 'trkid',
trkseg: 'trksegid',
trkpt: 'trkptid',
});
expect(rte).toBe('gpx/gpxid/trk/trkid/trksegid/trkptid');
});
test(', and versa', () => {
const rte = uri('trkpt', 'gpx/gpxid/trk/trkid/trksegid/trkptid');
expect(rte).toMatchObject({
gpx: 'gpxid',
trk: 'trkid',
trkseg: 'trksegid',
trkpt: 'trkptid',
});
});
});
describe('Checking settings id', () => {
test(', vice', () => {
const rte = uri('settings', {});
expect(rte).toBe('settings');
});
test(', and versa', () => {
const rte = uri('settings', 'settings');
expect(rte).toMatchObject({});
});
});
-21
View File
@@ -1,21 +0,0 @@
import { route } from 'docuri';
const routes = {
dbdef: route('dbdef'),
settings: route('settings'),
gpx: route('gpx/:gpx'),
trk: route('gpx/:gpx/trk/:trk'),
trkseg: route('gpx/:gpx/trk/:trk/:trkseg'),
trkpt: route('gpx/:gpx/trk/:trk/:trkseg/:trkpt'),
wpt: route('gpx/:gpx/wpt/:wpt'),
rte: route('gpx/:gpx/rte/:rte'),
rtept: route('gpx/:gpx/rte/:rte/:rtept'),
};
type RouteKey = keyof typeof routes;
const uri = (type: RouteKey, param: any) => {
return routes[type](param);
};
export default uri;
-25
View File
@@ -1,25 +0,0 @@
/**
*
* See https://www.pluralsight.com/guides/how-to-communicate-between-independent-components-in-reactjs (and many similar pages)
*
*
*/
const eventBus = {
on(event: string, callback: any) {
// ...
document.addEventListener(event, (e) => callback(e));
},
dispatch(event: string, data: any) {
// ...
document.dispatchEvent(new CustomEvent(event, { detail: data }));
},
remove(event: string, callback: (e: Event) => void) {
// ...
document.removeEventListener(event, callback);
},
};
export default eventBus;