Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Libraries
KPublicTransport
Commits
02d81104
Commit
02d81104
authored
Aug 11, 2021
by
Volker Krause
Browse files
Parse floor level change information from EFA transfer navigation paths
parent
cb78499c
Changes
5
Hide whitespace changes
Inline
Side-by-side
autotests/data/efa/trip-response-full-indoor-path-vgn.json
View file @
02d81104
...
...
@@ -91,6 +91,8 @@
},
{
"description"
:
"Aufzug abw�rts"
,
"floorLevelChange"
:
-2
,
"maneuver"
:
"Elevator"
,
"path"
:
{
"coordinates"
:
[
[
...
...
@@ -151,6 +153,8 @@
},
{
"description"
:
"Rolltreppe abw�rts"
,
"floorLevelChange"
:
-2
,
"maneuver"
:
"Escalator"
,
"path"
:
{
"coordinates"
:
[
[
...
...
@@ -239,6 +243,8 @@
},
{
"description"
:
"Rolltreppe aufw�rts"
,
"floorLevelChange"
:
4
,
"maneuver"
:
"Escalator"
,
"path"
:
{
"coordinates"
:
[
[
...
...
@@ -291,6 +297,8 @@
},
{
"description"
:
"Rolltreppe aufw�rts"
,
"floorLevelChange"
:
1
,
"maneuver"
:
"Escalator"
,
"path"
:
{
"coordinates"
:
[
[
...
...
src/lib/backends/efaxmlparser.cpp
View file @
02d81104
...
...
@@ -368,6 +368,7 @@ std::vector<JourneySection> EfaXmlParser::parseTripPartialRoute(ScopedXmlStreamR
}
if
(
!
pathDesc
.
empty
())
{
resolvePathDescription
(
pathDesc
);
if
(
!
transferPoly
.
empty
()
&&
section
.
mode
()
==
JourneySection
::
PublicTransport
)
{
// path description is actually for a subsequent transfer section
const
auto
path
=
assemblePath
(
pathDesc
,
transferPoly
);
...
...
@@ -474,9 +475,20 @@ std::vector<EfaXmlParser::PathDescription> EfaXmlParser::parsePathDescriptionLis
desc
.
description
=
elemReader
.
readElementText
();
}
else
if
(
elemReader
.
name
()
==
QLatin1String
(
"traveltime"
))
{
desc
.
travelTime
=
elemReader
.
readElementText
().
toInt
();
}
else
if
(
elemReader
.
name
()
==
QLatin1String
(
"niveau"
))
{
// seems to match OSM floor level, but is always "0" for elevators/escalators
desc
.
niveau
=
elemReader
.
readElementText
().
toInt
();
}
else
if
(
elemReader
.
name
()
==
QLatin1String
(
"genAttrList"
))
{
const
auto
attrs
=
parseGenericAttributeList
(
elemReader
.
subReader
());
const
auto
indoorType
=
attrs
.
value
(
QLatin1String
(
"INDOOR_TYPE"
));
if
(
indoorType
==
QLatin1String
(
"LIFT"
))
{
desc
.
maneuver
=
PathSection
::
Elevator
;
}
else
if
(
indoorType
==
QLatin1String
(
"ESCALATOR"
))
{
desc
.
maneuver
=
PathSection
::
Escalator
;
}
}
// NOTE: skyDirection seems flipped by 180°, ie. pointing to the start point, should we ever need that
// turnDirection, turningManoeuvre, from/toPathLink??
, niveau, genAttrList
// turnDirection, turningManoeuvre, from/toPathLink??
}
descs
.
push_back
(
std
::
move
(
desc
));
}
...
...
@@ -484,6 +496,22 @@ std::vector<EfaXmlParser::PathDescription> EfaXmlParser::parsePathDescriptionLis
return
descs
;
}
void
EfaXmlParser
::
resolvePathDescription
(
std
::
vector
<
PathDescription
>
&
descs
)
const
{
if
(
descs
.
size
()
<
3
)
{
return
;
}
for
(
auto
it
=
std
::
next
(
descs
.
begin
());
it
!=
std
::
prev
(
descs
.
end
());
++
it
)
{
if
((
*
it
).
maneuver
!=
PathSection
::
Elevator
&&
(
*
it
).
maneuver
!=
PathSection
::
Escalator
)
{
continue
;
}
const
auto
niveauBefore
=
(
*
std
::
prev
(
it
)).
niveau
;
const
auto
niveauAfter
=
(
*
std
::
next
(
it
)).
niveau
;
(
*
it
).
niveauDelta
=
niveauAfter
-
niveauBefore
;
}
}
Path
EfaXmlParser
::
assemblePath
(
const
std
::
vector
<
PathDescription
>
&
descs
,
const
QPolygonF
&
poly
)
const
{
Path
path
;
...
...
@@ -500,9 +528,31 @@ Path EfaXmlParser::assemblePath(const std::vector<PathDescription> &descs, const
std
::
copy
(
poly
.
begin
()
+
desc
.
fromIndex
,
poly
.
begin
()
+
desc
.
toIndex
+
1
,
std
::
back_inserter
(
subPoly
));
section
.
setPath
(
subPoly
);
section
.
setDescription
(
desc
.
description
);
section
.
setManeuver
(
desc
.
maneuver
);
section
.
setFloorLevelChange
(
desc
.
niveauDelta
);
sections
.
push_back
(
std
::
move
(
section
));
}
path
.
setSections
(
std
::
move
(
sections
));
return
path
;
}
QHash
<
QString
,
QString
>
EfaXmlParser
::
parseGenericAttributeList
(
ScopedXmlStreamReader
&&
reader
)
const
{
QHash
<
QString
,
QString
>
attrs
;
while
(
reader
.
readNextSibling
())
{
if
(
reader
.
name
()
==
QLatin1String
(
"genAttrElem"
))
{
auto
attrReader
=
reader
.
subReader
();
QString
name
,
value
;
while
(
attrReader
.
readNextSibling
())
{
if
(
attrReader
.
name
()
==
QLatin1String
(
"name"
))
{
name
=
attrReader
.
readElementText
();
}
else
if
(
attrReader
.
name
()
==
QLatin1String
(
"value"
))
{
value
=
attrReader
.
readElementText
();
}
}
attrs
.
insert
(
name
,
value
);
}
}
return
attrs
;
}
src/lib/backends/efaxmlparser.h
View file @
02d81104
...
...
@@ -9,6 +9,8 @@
#include
"efaparser.h"
#include
<KPublicTransport/Path>
#include
<QPointF>
class
QPolygonF
;
...
...
@@ -50,11 +52,15 @@ private:
int
toIndex
=
-
1
;
QString
description
;
int
travelTime
=
0
;
int
niveau
=
0
;
int
niveauDelta
=
0
;
PathSection
::
Maneuver
maneuver
=
PathSection
::
Move
;
};
std
::
vector
<
PathDescription
>
parsePathDescriptionList
(
ScopedXmlStreamReader
&&
reader
)
const
;
void
resolvePathDescription
(
std
::
vector
<
PathDescription
>
&
descs
)
const
;
Path
assemblePath
(
const
std
::
vector
<
PathDescription
>
&
descs
,
const
QPolygonF
&
poly
)
const
;
QHash
<
QString
,
QString
>
parseGenericAttributeList
(
ScopedXmlStreamReader
&&
reader
)
const
;
mutable
QHash
<
QString
,
Location
>
m_locations
;
};
...
...
src/lib/datatypes/path.cpp
View file @
02d81104
...
...
@@ -19,12 +19,16 @@ class PathSectionPrivate : public QSharedData {
public:
QPolygonF
path
;
QString
description
;
int
floorLevelChange
=
0
;
PathSection
::
Maneuver
maneuver
=
PathSection
::
Move
;
};
}
KPUBLICTRANSPORT_MAKE_GADGET
(
PathSection
)
KPUBLICTRANSPORT_MAKE_PROPERTY
(
PathSection
,
QPolygonF
,
path
,
setPath
)
KPUBLICTRANSPORT_MAKE_PROPERTY
(
PathSection
,
QString
,
description
,
setDescription
)
KPUBLICTRANSPORT_MAKE_PROPERTY
(
PathSection
,
int
,
floorLevelChange
,
setFloorLevelChange
)
KPUBLICTRANSPORT_MAKE_PROPERTY
(
PathSection
,
PathSection
::
Maneuver
,
maneuver
,
setManeuver
)
int
PathSection
::
distance
()
const
{
...
...
@@ -55,7 +59,7 @@ QPointF PathSection::startPoint() const
return
d
->
path
.
empty
()
?
QPointF
()
:
d
->
path
.
constFirst
();
}
QPointF
KPublicTransport
::
PathSection
::
endPoint
()
const
QPointF
PathSection
::
endPoint
()
const
{
return
d
->
path
.
empty
()
?
QPointF
()
:
d
->
path
.
constLast
();
}
...
...
@@ -66,6 +70,12 @@ QJsonObject PathSection::toJson(const PathSection §ion)
if
(
!
section
.
path
().
empty
())
{
obj
.
insert
(
QLatin1String
(
"path"
),
GeoJson
::
writeLineString
(
section
.
path
()));
}
if
(
section
.
maneuver
()
==
PathSection
::
Move
)
{
obj
.
remove
(
QLatin1String
(
"maneuver"
));
}
if
(
section
.
floorLevelChange
()
==
0
)
{
obj
.
remove
(
QLatin1String
(
"floorLevelChange"
));
}
return
obj
;
}
...
...
src/lib/datatypes/path.h
View file @
02d81104
...
...
@@ -36,6 +36,22 @@ class KPUBLICTRANSPORT_EXPORT PathSection
/** The overall direction of this section in degree. */
Q_PROPERTY
(
int
direction
READ
direction
STORED
false
)
/** Floor level change during this path section.
* Negative values indicate going down, positive values indicate going up
*/
KPUBLICTRANSPORT_PROPERTY
(
int
,
floorLevelChange
,
setFloorLevelChange
)
public:
/** Maneuver associated with a path section. */
enum
Maneuver
{
Move
,
///< Move/drive with the default mode of transport for this path
Elevator
,
///< Take an elevator
Escalator
,
///< Take an escalator
};
Q_ENUM
(
Maneuver
)
/** Movement maneuver for this path section. */
KPUBLICTRANSPORT_PROPERTY
(
Maneuver
,
maneuver
,
setManeuver
)
public:
/** Length of this path section in meters. */
int
distance
()
const
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment