FPTF location objects

see public-transport/friendly-public-transport-format@6481dee
This commit is contained in:
Jannis R 2017-12-11 19:25:29 +01:00
parent 14cdc77c0f
commit 3811b4553c
No known key found for this signature in database
GPG key ID: 0FE83946296A88A5
6 changed files with 78 additions and 66 deletions

View file

@ -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",

View file

@ -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
} }

View file

@ -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,

View file

@ -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()
})) }))

View file

@ -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) => {

View file

@ -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) {