mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 15:19:35 +02:00
FPTF location objects
see public-transport/friendly-public-transport-format@6481dee
This commit is contained in:
parent
14cdc77c0f
commit
3811b4553c
6 changed files with 78 additions and 66 deletions
|
@ -40,6 +40,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"co": "^4.6.0",
|
"co": "^4.6.0",
|
||||||
"db-stations": "^1.25.0",
|
"db-stations": "^1.25.0",
|
||||||
|
"is-coordinates": "^2.0.2",
|
||||||
"is-roughly-equal": "^0.1.0",
|
"is-roughly-equal": "^0.1.0",
|
||||||
"tap-spec": "^4.1.1",
|
"tap-spec": "^4.1.1",
|
||||||
"tape": "^4.8.0",
|
"tape": "^4.8.0",
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const types = Object.create(null)
|
const POI = 'P'
|
||||||
types.P = 'poi'
|
const STATION = 'S'
|
||||||
types.S = 'station'
|
const ADDRESS = 'A'
|
||||||
types.A = 'address'
|
|
||||||
|
|
||||||
// todo: what is s.rRefL?
|
// todo: what is s.rRefL?
|
||||||
// todo: is passing in profile necessary?
|
// todo: is passing in profile necessary?
|
||||||
const parseLocation = (profile, l) => {
|
const parseLocation = (profile, l) => {
|
||||||
const type = types[l.type] || 'unknown'
|
const res = {type: 'location'}
|
||||||
const res = {
|
if (l.crd) {
|
||||||
type,
|
res.latitude = l.crd.y / 1000000
|
||||||
name: l.name,
|
res.longitude = l.crd.x / 1000000
|
||||||
coordinates: l.crd ? {
|
|
||||||
latitude: l.crd.y / 1000000,
|
|
||||||
longitude: l.crd.x / 1000000
|
|
||||||
} : null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'poi' || type === 'station') res.id = l.extId
|
if (l.type === STATION) {
|
||||||
if ('pCls' in l) res.products = profile.parseProducts(l.pCls)
|
const station = {
|
||||||
|
type: 'station',
|
||||||
|
id: l.extId,
|
||||||
|
location: res
|
||||||
|
}
|
||||||
|
if ('pCls' in l) station.products = profile.parseProducts(l.pCls)
|
||||||
|
return station
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === POI) res.id = l.extId
|
||||||
|
else if (l.type === ADDRESS) res.address = l.name
|
||||||
|
else res.name = l.name
|
||||||
|
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ const createParseMovement = (profile, locations, lines, remarks) => {
|
||||||
const res = {
|
const res = {
|
||||||
direction: profile.parseStationName(m.dirTxt),
|
direction: profile.parseStationName(m.dirTxt),
|
||||||
line: lines[m.prodX] || null,
|
line: lines[m.prodX] || null,
|
||||||
coordinates: m.pos ? {
|
location: m.pos ? {
|
||||||
|
type: 'location',
|
||||||
latitude: m.pos.y / 1000000,
|
latitude: m.pos.y / 1000000,
|
||||||
longitude: m.pos.x / 1000000
|
longitude: m.pos.x / 1000000
|
||||||
} : null,
|
} : null,
|
||||||
|
|
20
test/db.js
20
test/db.js
|
@ -53,18 +53,18 @@ const isJungfernheide = (s) => {
|
||||||
return s.type === 'station' &&
|
return s.type === 'station' &&
|
||||||
(s.id === '008011167' || s.id === '8011167') &&
|
(s.id === '008011167' || s.id === '8011167') &&
|
||||||
s.name === 'Berlin Jungfernheide' &&
|
s.name === 'Berlin Jungfernheide' &&
|
||||||
s.coordinates &&
|
s.location &&
|
||||||
isRoughlyEqual(s.coordinates.latitude, 52.530408, .0005) &&
|
isRoughlyEqual(s.location.latitude, 52.530408, .0005) &&
|
||||||
isRoughlyEqual(s.coordinates.longitude, 13.299424, .0005)
|
isRoughlyEqual(s.location.longitude, 13.299424, .0005)
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertIsJungfernheide = (t, s) => {
|
const assertIsJungfernheide = (t, s) => {
|
||||||
t.equal(s.type, 'station')
|
t.equal(s.type, 'station')
|
||||||
t.ok(s.id === '008011167' || s.id === '8011167', 'id should be 8011167')
|
t.ok(s.id === '008011167' || s.id === '8011167', 'id should be 8011167')
|
||||||
t.equal(s.name, 'Berlin Jungfernheide')
|
t.equal(s.name, 'Berlin Jungfernheide')
|
||||||
t.ok(s.coordinates)
|
t.ok(s.location)
|
||||||
t.ok(isRoughlyEqual(s.coordinates.latitude, 52.530408, .0005))
|
t.ok(isRoughlyEqual(s.location.latitude, 52.530408, .0005))
|
||||||
t.ok(isRoughlyEqual(s.coordinates.longitude, 13.299424, .0005))
|
t.ok(isRoughlyEqual(s.location.longitude, 13.299424, .0005))
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertValidProducts = (t, p) => {
|
const assertValidProducts = (t, p) => {
|
||||||
|
@ -170,8 +170,8 @@ test('Berlin Jungfernheide to Torfstraße 17', co.wrap(function* (t) {
|
||||||
const d = part.destination
|
const d = part.destination
|
||||||
assertValidAddress(t, d)
|
assertValidAddress(t, d)
|
||||||
t.equal(d.name, 'Torfstraße 17')
|
t.equal(d.name, 'Torfstraße 17')
|
||||||
t.ok(isRoughlyEqual(.0001, d.coordinates.latitude, 52.5416823))
|
t.ok(isRoughlyEqual(.0001, d.latitude, 52.5416823))
|
||||||
t.ok(isRoughlyEqual(.0001, d.coordinates.longitude, 13.3491223))
|
t.ok(isRoughlyEqual(.0001, d.longitude, 13.3491223))
|
||||||
|
|
||||||
t.end()
|
t.end()
|
||||||
}))
|
}))
|
||||||
|
@ -199,8 +199,8 @@ test('Berlin Jungfernheide to ATZE Musiktheater', co.wrap(function* (t) {
|
||||||
const d = part.destination
|
const d = part.destination
|
||||||
assertValidPoi(t, d)
|
assertValidPoi(t, d)
|
||||||
t.equal(d.name, 'ATZE Musiktheater')
|
t.equal(d.name, 'ATZE Musiktheater')
|
||||||
t.ok(isRoughlyEqual(.0001, d.coordinates.latitude, 52.542399))
|
t.ok(isRoughlyEqual(.0001, d.latitude, 52.542399))
|
||||||
t.ok(isRoughlyEqual(.0001, d.coordinates.longitude, 13.350402))
|
t.ok(isRoughlyEqual(.0001, d.longitude, 13.350402))
|
||||||
|
|
||||||
t.end()
|
t.end()
|
||||||
}))
|
}))
|
||||||
|
|
66
test/util.js
66
test/util.js
|
@ -2,53 +2,57 @@
|
||||||
|
|
||||||
const isRoughlyEqual = require('is-roughly-equal')
|
const isRoughlyEqual = require('is-roughly-equal')
|
||||||
const {DateTime} = require('luxon')
|
const {DateTime} = require('luxon')
|
||||||
|
const isValidWGS84 = require('is-coordinates')
|
||||||
|
|
||||||
const assertValidStation = (t, s, coordsOptional = false) => {
|
const assertValidStation = (t, s, coordsOptional = false) => {
|
||||||
t.equal(typeof s.type, 'string')
|
|
||||||
t.equal(s.type, 'station')
|
t.equal(s.type, 'station')
|
||||||
t.equal(typeof s.id, 'string')
|
t.equal(typeof s.id, 'string')
|
||||||
|
t.ok(s.id)
|
||||||
t.equal(typeof s.name, 'string')
|
t.equal(typeof s.name, 'string')
|
||||||
if (!coordsOptional) {
|
t.ok(s.name)
|
||||||
if (!s.coordinates) console.trace()
|
|
||||||
t.ok(s.coordinates)
|
if (!coordsOptional || (s.location !== null && s.location !== undefined)) {
|
||||||
}
|
t.ok(s.location)
|
||||||
if (s.coordinates) {
|
assertValidLocation(t, s.location, coordsOptional)
|
||||||
t.equal(typeof s.coordinates.latitude, 'number')
|
|
||||||
t.equal(typeof s.coordinates.longitude, 'number')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertValidPoi = (t, p) => {
|
const assertValidPoi = (t, p) => {
|
||||||
t.equal(typeof p.type, 'string')
|
|
||||||
t.equal(p.type, 'poi')
|
|
||||||
t.equal(typeof p.id, 'string')
|
t.equal(typeof p.id, 'string')
|
||||||
|
|
||||||
t.equal(typeof p.name, 'string')
|
t.equal(typeof p.name, 'string')
|
||||||
t.ok(p.coordinates)
|
t.equal(typeof a.address, 'string') // todo: do POIs always have an address?
|
||||||
if (p.coordinates) {
|
assertValidLocation(t, a, true) // todo: do POIs always have coords?
|
||||||
t.equal(typeof p.coordinates.latitude, 'number')
|
|
||||||
t.equal(typeof p.coordinates.longitude, 'number')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertValidAddress = (t, a) => {
|
const assertValidAddress = (t, a) => {
|
||||||
t.equal(typeof a.type, 'string')
|
t.equal(typeof a.address, 'string')
|
||||||
t.equal(a.type, 'address')
|
assertValidLocation(t, a, true) // todo: do addresses always have coords?
|
||||||
|
|
||||||
t.equal(typeof a.name, 'string')
|
|
||||||
t.ok(a.coordinates)
|
|
||||||
if (a.coordinates) {
|
|
||||||
t.equal(typeof a.coordinates.latitude, 'number')
|
|
||||||
t.equal(typeof a.coordinates.longitude, 'number')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const assertValidLocation = (t, l) => {
|
const assertValidLocation = (t, l, coordsOptional = false) => {
|
||||||
if (l.type === 'station') assertValidStation(t, l)
|
t.equal(l.type, 'location')
|
||||||
else if (l.type === 'poi') assertValidPoi(t, l)
|
if (l.name !== null && l.name !== undefined) {
|
||||||
else if (l.type === 'address') assertValidAddress(t, l)
|
t.equal(typeof l.name, 'string')
|
||||||
else t.fail('invalid type ' + l.type)
|
t.ok(l.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l.address !== null && l.address !== undefined) {
|
||||||
|
t.equal(typeof l.address, 'string')
|
||||||
|
t.ok(l.address)
|
||||||
|
}
|
||||||
|
|
||||||
|
const hasLatitude = l.latitude !== null && l.latitude !== undefined
|
||||||
|
const hasLongitude = l.longitude !== null && l.longitude !== undefined
|
||||||
|
if (!coordsOptional && hasLatitude) t.equal(typeof l.latitude, 'number')
|
||||||
|
if (!coordsOptional && hasLongitude) t.equal(typeof l.longitude, 'number')
|
||||||
|
if ((hasLongitude && !hasLatitude) || (hasLatitude && !hasLongitude)) {
|
||||||
|
t.fail('should have both .latitude and .longitude')
|
||||||
|
}
|
||||||
|
if (hasLatitude && hasLongitude) isValidWGS84([l.longitude, l.latitude])
|
||||||
|
|
||||||
|
if (!coordsOptional && l.altitude !== null && l.altitude !== undefined) {
|
||||||
|
t.equal(typeof l.altitude, 'number')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isValidMode = (m) => {
|
const isValidMode = (m) => {
|
||||||
|
|
20
test/vbb.js
20
test/vbb.js
|
@ -204,8 +204,8 @@ test('journeys – station to address', co.wrap(function* (t) {
|
||||||
const dest = part.destination
|
const dest = part.destination
|
||||||
assertValidAddress(t, dest)
|
assertValidAddress(t, dest)
|
||||||
t.strictEqual(dest.name, 'Torfstr. 17')
|
t.strictEqual(dest.name, 'Torfstr. 17')
|
||||||
t.ok(isRoughlyEqual(.0001, dest.coordinates.latitude, 52.5416823))
|
t.ok(isRoughlyEqual(.0001, dest.latitude, 52.5416823))
|
||||||
t.ok(isRoughlyEqual(.0001, dest.coordinates.longitude, 13.3491223))
|
t.ok(isRoughlyEqual(.0001, dest.longitude, 13.3491223))
|
||||||
assertValidWhen(t, part.arrival)
|
assertValidWhen(t, part.arrival)
|
||||||
|
|
||||||
t.end()
|
t.end()
|
||||||
|
@ -231,8 +231,8 @@ test('journeys – station to POI', co.wrap(function* (t) {
|
||||||
const dest = part.destination
|
const dest = part.destination
|
||||||
assertValidPoi(t, dest)
|
assertValidPoi(t, dest)
|
||||||
t.strictEqual(dest.name, 'ATZE Musiktheater')
|
t.strictEqual(dest.name, 'ATZE Musiktheater')
|
||||||
t.ok(isRoughlyEqual(.0001, dest.coordinates.latitude, 52.543333))
|
t.ok(isRoughlyEqual(.0001, dest.latitude, 52.543333))
|
||||||
t.ok(isRoughlyEqual(.0001, dest.coordinates.longitude, 13.351686))
|
t.ok(isRoughlyEqual(.0001, dest.longitude, 13.351686))
|
||||||
assertValidWhen(t, part.arrival)
|
assertValidWhen(t, part.arrival)
|
||||||
|
|
||||||
t.end()
|
t.end()
|
||||||
|
@ -322,12 +322,12 @@ test('radar', co.wrap(function* (t) {
|
||||||
t.ok(findStation(v.direction))
|
t.ok(findStation(v.direction))
|
||||||
assertValidLine(t, v.line)
|
assertValidLine(t, v.line)
|
||||||
|
|
||||||
t.equal(typeof v.coordinates.latitude, 'number')
|
t.equal(typeof v.location.latitude, 'number')
|
||||||
t.ok(v.coordinates.latitude <= 55, 'vehicle is too far away')
|
t.ok(v.location.latitude <= 55, 'vehicle is too far away')
|
||||||
t.ok(v.coordinates.latitude >= 45, 'vehicle is too far away')
|
t.ok(v.location.latitude >= 45, 'vehicle is too far away')
|
||||||
t.equal(typeof v.coordinates.longitude, 'number')
|
t.equal(typeof v.location.longitude, 'number')
|
||||||
t.ok(v.coordinates.longitude >= 9, 'vehicle is too far away')
|
t.ok(v.location.longitude >= 9, 'vehicle is too far away')
|
||||||
t.ok(v.coordinates.longitude <= 15, 'vehicle is too far away')
|
t.ok(v.location.longitude <= 15, 'vehicle is too far away')
|
||||||
|
|
||||||
t.ok(Array.isArray(v.nextStops))
|
t.ok(Array.isArray(v.nextStops))
|
||||||
for (let st of v.nextStops) {
|
for (let st of v.nextStops) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue