1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
package Travel::Status::DE::EFA::Trip;
use strict;
use warnings;
use 5.010;
use DateTime::Format::Strptime;
use Travel::Status::DE::EFA::Stop;
use parent 'Class::Accessor';
our $VERSION = '3.01';
Travel::Status::DE::EFA::Trip->mk_ro_accessors(
qw(operator product product_class name line number type id dest_name dest_id)
);
sub new {
my ( $obj, %conf ) = @_;
my $json = $conf{json}{transportation};
my $ref = {
operator => $json->{operator}{name},
product => $json->{product}{name},
product_class => $json->{product}{class},
polyline => $json->{coords},
name => $json->{name},
line => $json->{disassembledName},
number => $json->{properties}{trainNumber},
type => $json->{properties}{trainType} // $json->{product}{name},
id => $json->{id},
dest_name => $json->{destination}{name},
dest_id => $json->{destination}{id},
route_raw => $json->{locationSequence},
strptime_obj => DateTime::Format::Strptime->new(
pattern => '%Y-%m-%dT%H:%M:%SZ',
time_zone => 'UTC'
),
};
if ( ref( $ref->{polyline} ) eq 'ARRAY' and @{ $ref->{polyline} } == 1 ) {
$ref->{polyline} = $ref->{polyline}[0];
}
return bless( $ref, $obj );
}
sub polyline {
my ($self) = @_;
return @{ $self->{polyline} // [] };
}
sub parse_dt {
my ( $self, $value ) = @_;
if ($value) {
my $dt = $self->{strptime_obj}->parse_datetime($value);
if ($dt) {
return $dt->set_time_zone('Europe/Berlin');
}
}
return undef;
}
sub route {
my ($self) = @_;
if ( $self->{route} ) {
return @{ $self->{route} };
}
for my $stop ( @{ $self->{route_raw} // [] } ) {
my $chain = $stop;
my ( $platform, $place, $name, $name_full, $stop_id );
while ( $chain->{type} ) {
if ( $chain->{type} eq 'platform' ) {
$platform = $chain->{properties}{platformName}
// $chain->{properties}{platform};
}
elsif ( $chain->{type} eq 'stop' ) {
$name = $chain->{disassembledName};
$name_full = $chain->{name};
$stop_id = $chain->{properties}{stopId};
}
elsif ( $chain->{type} eq 'locality' ) {
$place = $chain->{name};
}
$chain = $chain->{parent};
}
push(
@{ $self->{route} },
Travel::Status::DE::EFA::Stop->new(
sched_arr => $self->parse_dt( $stop->{arrivalTimePlanned} ),
sched_dep => $self->parse_dt( $stop->{departureTimePlanned} ),
rt_arr => $self->parse_dt( $stop->{arrivalTimeEstimated} ),
rt_dep => $self->parse_dt( $stop->{departureTimeEstimated} ),
latlon => $stop->{coord},
full_name => $name_full,
name => $name,
place => $place,
niveau => $stop->{niveau},
platform => $platform,
id => $stop->{id},
stop_id => $stop_id,
)
);
}
delete $self->{route_raw};
return @{ $self->{route} // [] };
}
sub TO_JSON {
my ($self) = @_;
# lazy loading
$self->route;
my $ret = { %{$self} };
delete $ret->{strptime_obj};
return $ret;
}
1;
|