Initial commit
This commit is contained in:
commit
05abd1789b
32 changed files with 1859 additions and 0 deletions
147
htdocs/css/infoboards.css
Normal file
147
htdocs/css/infoboards.css
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*** Stop info board ***************************************************************/
|
||||
.stopInfoboard {
|
||||
width: 100%;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
margin: 0 auto 1em;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
.stopInfoboard {
|
||||
width: auto;
|
||||
min-width: 30%;
|
||||
max-width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0.4em 0.1em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
td {
|
||||
padding: 0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
.noLines {
|
||||
font-style: italic;
|
||||
color: #777;
|
||||
}
|
||||
|
||||
|
||||
/*** Shared info board styles ******************************************************/
|
||||
tr.line.even td {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
tr.line .lineNumber {
|
||||
text-align: right;
|
||||
width: 3em;
|
||||
font-size: 80%;
|
||||
font-weight: bold;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
tr.line .lineNumber {
|
||||
font-size: 100%;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
||||
tr.line .destination {
|
||||
font-size: 85%;
|
||||
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
tr.line .destination {
|
||||
font-size: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.delay {
|
||||
font-size: 90%;
|
||||
color: #daa;
|
||||
margin-right: 0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
.delay.early {
|
||||
color: #aad;
|
||||
}
|
||||
|
||||
.departureH {
|
||||
width: 0;
|
||||
text-align: right;
|
||||
padding-right: 0;
|
||||
}
|
||||
.departureSep {
|
||||
width: 0;
|
||||
text-align: center;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
.departureMS {
|
||||
width: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
.departureH {
|
||||
padding-left: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.theoretical {
|
||||
font-size: 90%;
|
||||
color: #a00;
|
||||
font-family: sans;
|
||||
}
|
||||
.seconds {
|
||||
font-size: 90%;
|
||||
color: #888;
|
||||
}
|
||||
table .seconds {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
|
||||
.disturbance {
|
||||
background: #fff8e0;
|
||||
border: 1px solid #ffd800;
|
||||
max-width: 50em;
|
||||
margin: 0 auto 1em;
|
||||
padding: 0.2em 0.4em;
|
||||
}
|
||||
.disturbance ul, .disturbance li, .disturbance p {
|
||||
margin: 0;
|
||||
margin-top: 0.2em;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.disturbance h3, .disturbance h4 {
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
}
|
||||
.disturbance h3 {
|
||||
margin: -0.2em -0.4em 0;
|
||||
padding: 0.2em 0.4em;
|
||||
background: #fff0a0;
|
||||
border-bottom: 1px solid #ffd800;
|
||||
}
|
||||
|
||||
.disturbance p.affectedLines {
|
||||
font-size: 70%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.affectedLines .line-nr {
|
||||
padding: 0 0.05em;
|
||||
}
|
||||
|
||||
tr.canceled.line.even td {
|
||||
background: #edd;
|
||||
}
|
||||
tr.canceled.line.odd td {
|
||||
background: #fee;
|
||||
}
|
142
htdocs/css/main.css
Normal file
142
htdocs/css/main.css
Normal file
|
@ -0,0 +1,142 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 0 0 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.group-text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.deemphasize {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
input {
|
||||
font-size: inherit;
|
||||
max-width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
input[type=text] {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*** Invisible space for correct text wrapping *************************************/
|
||||
.invisiblespace {
|
||||
font-size: 0pt;
|
||||
}
|
||||
|
||||
|
||||
/*** Header and footer *************************************************************/
|
||||
.header {
|
||||
background-color: #2b3034;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #ffd800;
|
||||
padding: 0.5em 0;
|
||||
text-align: center;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
.header {
|
||||
padding: 1em 0;
|
||||
}
|
||||
}
|
||||
|
||||
h1, .subtitle {
|
||||
display: inline-block;
|
||||
}
|
||||
.subtitle {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
h1, h2 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 120%;
|
||||
}
|
||||
h1 a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
h2 {
|
||||
margin-top: 1em;
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
h1 {
|
||||
font-size: 160%;
|
||||
}
|
||||
h2 {
|
||||
font-size: 140%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.info, .footnote {
|
||||
text-align: center;
|
||||
padding: 0 1em;
|
||||
}
|
||||
.info {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.info .stopref {
|
||||
margin: 0.4em 0;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
.info {
|
||||
width: 400px;
|
||||
text-align: right;
|
||||
min-width: 30%;
|
||||
max-width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.info .stopref {
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-search div {
|
||||
margin: 0.3em 0;
|
||||
}
|
||||
|
||||
|
||||
/*** Search elements ***************************************************************/
|
||||
.mainsearch input {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
.mainsearch input {
|
||||
font-size: 140%;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
/*** Error messages ***************************************************************/
|
||||
.user-error {
|
||||
color: #333;
|
||||
margin: 1em 0;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
/*** Line numbers ******************************************************************/
|
||||
span.line-nr {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 2em;
|
||||
padding: 0.1em;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
span.small.line-nr {
|
||||
font-size: 75%;
|
||||
}
|
27
htdocs/css/searchresults.css
Normal file
27
htdocs/css/searchresults.css
Normal file
|
@ -0,0 +1,27 @@
|
|||
.search-results .result {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.search-results a.result.stop {
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.search-results .result.stop .name {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.search-results .result.stop .ref {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.search-results .result.stop .dest,
|
||||
.search-results .result.stop .lines {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.search-results .result.stop .not-served-msg {
|
||||
color: #800;
|
||||
}
|
||||
|
141
htdocs/img/delijn-pixelperfect.svg
Normal file
141
htdocs/img/delijn-pixelperfect.svg
Normal file
|
@ -0,0 +1,141 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
id="svg3187"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="delijn-pixelperfect.svg"
|
||||
inkscape:export-filename="favicon-32.png"
|
||||
inkscape:export-xdpi="180"
|
||||
inkscape:export-ydpi="180">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="997"
|
||||
id="namedview61"
|
||||
showgrid="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:zoom="22.627417"
|
||||
inkscape:cx="16.153472"
|
||||
inkscape:cy="8.4656119"
|
||||
inkscape:window-x="-5"
|
||||
inkscape:window-y="-10"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3187"
|
||||
showborder="false">
|
||||
<inkscape:grid
|
||||
empspacing="4"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="0.25px"
|
||||
spacingy="0.25px"
|
||||
type="xygrid"
|
||||
id="grid3038" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs3189" />
|
||||
<metadata
|
||||
id="metadata3192">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1;stroke-width:0.50000000000000000;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
d="m -1,-1 18,0 0,18 -18,0 z"
|
||||
id="rect4215"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3023"
|
||||
d="m 11,6 -2,0 0,4 2,0 0,-2 2,2 2,0 0,-4 -2,0 0,2 z"
|
||||
sodipodi:nodetypes="ccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3027"
|
||||
d="M 2,9 2,6 0,6 0,10 3,10 3,9 z"
|
||||
sodipodi:nodetypes="ccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3031"
|
||||
d="M 5,6 3,6 3,8 5,8 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3043"
|
||||
d="M 5.5,9 5,9 l 0,1 2,0 c 0.5,0 1,0 1,-1 L 8,6 6,6 6,8.5 C 6,9 5.75,9 5.5,9 z"
|
||||
sodipodi:nodetypes="ccccccccc" />
|
||||
<path
|
||||
style="fill:#ffd800;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 0,2 16,2 16,0 z"
|
||||
id="path3047"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#ffd800;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,11 0,5 16,0 0,-5 z"
|
||||
id="path3051"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3055"
|
||||
d="m 4.25,4 0.5,0 0,-0.25 -0.5,0 0,-0.25 L 5,3.5 5,3 3.75,3 3.75,5 5,5 5,4.5 4.25,4.5 z"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3059"
|
||||
d="M 3.5,4 C 3.5,3.25 3.25,3 3,3 L 2,3 2,5 3,5 C 3.25,5 3.5,4.75 3.5,4 z m -1,0.5 0,-1 C 2.75,3.5 3,3.5 3,4 3,4.5 2.75,4.5 2.5,4.5 z"
|
||||
sodipodi:nodetypes="sccccsccsc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3067"
|
||||
d="M 9,5 9,3 6,3 6,5 z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#004494;fill-opacity:1;stroke:none"
|
||||
d="m 10,3 2,0 0,2 -2,0 z"
|
||||
id="rect4206"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#004494;fill-opacity:1;stroke:none"
|
||||
d="m 13,3 1,0 0,2 -1,0 z"
|
||||
id="rect4208"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:#004494;fill-opacity:1;stroke:none"
|
||||
d="m 15,3 1,0 0,2 -1,0 z"
|
||||
id="rect4212" />
|
||||
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
166
htdocs/img/delijn.svg
Normal file
166
htdocs/img/delijn.svg
Normal file
|
@ -0,0 +1,166 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
id="svg3187"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="delijn.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="997"
|
||||
id="namedview61"
|
||||
showgrid="true"
|
||||
inkscape:showpageshadow="false"
|
||||
inkscape:zoom="33.941126"
|
||||
inkscape:cx="7.4231543"
|
||||
inkscape:cy="6.3421583"
|
||||
inkscape:window-x="-5"
|
||||
inkscape:window-y="-10"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3187">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3038"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true"
|
||||
spacingx="0.5px"
|
||||
spacingy="0.5px" />
|
||||
</sodipodi:namedview>
|
||||
<defs
|
||||
id="defs3189" />
|
||||
<metadata
|
||||
id="metadata3192">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3023"
|
||||
d="m 7.8137831,5.8602123 -1.3288861,0 -0.4579433,2.5911185 1.3288861,0 0.2027545,-1.1520314 0.4447395,1.1520314 1.3964286,0 0.4579433,-2.5901028 -1.3960478,0 -0.2065632,1.1616803 -0.4413116,-1.162696 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3027"
|
||||
d="m 1.5755977,7.8146792 0.3439336,-1.9534004 -1.43540528,0 -0.45591192,2.5913724 2.2421065,0 0.1119784,-0.637972 -0.8067013,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3031"
|
||||
d="m 4.1864457,5.8624671 -1.4587658,0 -0.3208269,1.8119674 1.4583849,0 0.3212078,-1.8119674 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3043"
|
||||
d="M 4.2852081,7.6183433 C 4.2589275,7.7667591 4.2020496,7.8143689 4.0917217,7.8143689 L 3.8405956,7.8132263 3.7281094,8.4524679 4.750515,8.4527218 c 0.5513856,0 0.8616748,-0.292134 0.9787316,-0.9557519 l 0.2881983,-1.6346048 -1.4233441,0 -0.3088927,1.7559782 z" />
|
||||
<path
|
||||
style="fill:#ffd800;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 5.46875 0.875 L 4.875 4.34375 L 15.375 4.34375 L 16 0.875 L 5.46875 0.875 z "
|
||||
id="path3047" />
|
||||
<path
|
||||
style="fill:#ffd800;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 4.0625 8.875 L 2.8125 16 L 13.34375 16 L 14.59375 8.875 L 4.0625 8.875 z "
|
||||
id="path3051" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3055"
|
||||
d="m 4.0943878,5.1596437 0.1174376,0 0.022726,-0.1268326 -0.1176916,0 0.017267,-0.08811 0.2116416,0 0.027296,-0.1630161 -0.5268823,0 -0.1141367,0.6458435 0.5270093,0 0.030343,-0.1694911 -0.2111338,-1.27e-4 0.016124,-0.098267 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#576065;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3059"
|
||||
d="M 3.470064,5.4189967 C 3.576964,5.3958901 3.6861492,5.3225074 3.7262685,5.0988046 3.7576275,4.9229655 3.6772621,4.8299042 3.6126396,4.8034966 3.5600784,4.7822943 3.4738728,4.7817865 3.4251203,4.7817865 L 2.9175358,4.7815325 2.8041609,5.42763 l 0.5086002,0 c 0.038977,0 0.1052495,0.00254 0.1573029,-0.00863 m -0.2711857,-0.1641588 -0.045325,0 0.052942,-0.30775 0.045324,0 c 0,0 0.050403,-0.00267 0.087094,0.00774 0.031359,0.00914 0.070844,0.060687 0.056116,0.1433374 -0.018917,0.1052495 -0.071859,0.1416869 -0.1221352,0.1524785 -0.024503,0.00533 -0.074017,0.00419 -0.074017,0.00419" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3063"
|
||||
d="m 9.9322061,5.4288742 0.1141369,-0.6467322 -1.9619069,0 -0.1140097,0.6467322 1.9617797,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3067"
|
||||
d="m 7.8823291,5.4288742 0.1141367,-0.6467322 -3.211824,0 -0.1141367,0.6467322 3.211824,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3071"
|
||||
d="m 11.18771,5.4288742 0.114264,-0.6467322 -1.163204,0 -0.11401,0.6467322 1.16295,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3075"
|
||||
d="m 11.978236,5.4288742 0.114137,-0.6467322 -0.685963,0 -0.114137,0.6467322 0.685963,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3079"
|
||||
d="m 12.521382,5.4288742 0.114137,-0.6467322 -0.421633,0 -0.11401,0.6467322 0.421506,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3083"
|
||||
d="m 12.920581,5.4288742 0.114137,-0.6467322 -0.261029,0 -0.114137,0.6467322 0.261029,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3087"
|
||||
d="m 13.231391,5.4288742 0.114137,-0.6467322 -0.149813,0 -0.114136,0.6467322 0.149812,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3091"
|
||||
d="m 13.540715,5.4288742 0.114137,-0.6467322 -0.116168,0 -0.114137,0.6467322 0.116168,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3095"
|
||||
d="m 13.810695,5.4288742 0.114137,-0.6467322 -0.07148,0 -0.114136,0.6467322 0.07148,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3099"
|
||||
d="m 14.112148,5.4288742 0.11401,-0.6467322 -0.0551,0 -0.114136,0.6467322 0.05523,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3103"
|
||||
d="m 14.431007,5.4288742 0.114137,-0.6467322 -0.05129,0 -0.113883,0.6467322 0.05104,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3107"
|
||||
d="m 14.781987,5.4288742 0.114137,-0.6467322 -0.03923,0 -0.114137,0.6467322 0.03923,0 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#004494;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
id="path3111"
|
||||
d="m 15.193234,5.4288742 0.114137,-0.6467322 -0.03073,0 -0.114136,0.6467322 0.03072,0 z" />
|
||||
</svg>
|
After Width: | Height: | Size: 7.4 KiB |
BIN
htdocs/img/favicon-32.ico
Normal file
BIN
htdocs/img/favicon-32.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
BIN
htdocs/img/favicon-32.png
Normal file
BIN
htdocs/img/favicon-32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 412 B |
BIN
htdocs/img/favicon.ico
Normal file
BIN
htdocs/img/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
BIN
htdocs/img/favicon.png
Normal file
BIN
htdocs/img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 308 B |
64
htdocs/index.php
Normal file
64
htdocs/index.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
error_reporting(0);
|
||||
ini_set('display_errors', 'Off');
|
||||
|
||||
require('./main.php');
|
||||
|
||||
|
||||
$ui;
|
||||
|
||||
// Display stop info board or search for stops
|
||||
if (isset($_GET['h']) && $_GET['h']) {
|
||||
$stop = $_GET['h'];
|
||||
|
||||
if (preg_match('/^\d{5,}$/', $stop) === 1) {
|
||||
|
||||
$ui = new StopInfoboard($stop);
|
||||
|
||||
} else {
|
||||
|
||||
$searchquery = new SearchQuery($stop, SEARCH_STOPS);
|
||||
$searchresults = $searchquery->execute();
|
||||
|
||||
$ui = new ResultsInterface($stop, $searchresults);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Display line info board or search for lines
|
||||
/* elseif (isset($_GET['l'])) {
|
||||
$lineRef = $_GET['l'];
|
||||
|
||||
$ui = new LineInfoboard($lineRef);
|
||||
}*/
|
||||
|
||||
// Show search interface
|
||||
else {
|
||||
$ui = new SearchUI();
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=240, initial-scale=1" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<link rel="shortcut icon" href="img/favicon.ico" />
|
||||
<title><?php $title = $ui->title(); if ($title) echo $title . ' – '; ?>De Lijn Reisinformatie lite</title>
|
||||
<style>
|
||||
@import url('css/main.css');
|
||||
@import url('css/searchresults.css');
|
||||
@import url('css/infoboards.css');
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
$ui->display();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
39
htdocs/main.php
Normal file
39
htdocs/main.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
$timezone = new DateTimeZone('Europe/Brussels');
|
||||
|
||||
$includesDir = '/mnt/imagestore/rumores.eu/delijnincludes/';
|
||||
|
||||
/*** API's ***/
|
||||
require($includesDir.'/ApiRequest.php');
|
||||
require($includesDir.'/ApiCoreRequest.php');
|
||||
require($includesDir.'/ApiSearchRequest.php');
|
||||
|
||||
require($includesDir.'/SearchQuery.php');
|
||||
|
||||
/*** HTML tools and UIs ***/
|
||||
require($includesDir.'/HTMLTools.php');
|
||||
require($includesDir.'/UI.php');
|
||||
|
||||
require($includesDir.'/Infoboard.php');
|
||||
require($includesDir.'/StopInfoboard.php');
|
||||
require($includesDir.'/LineInfoboard.php');
|
||||
|
||||
require($includesDir.'/ResultsInterface.php');
|
||||
|
||||
require($includesDir.'/SearchUI.php');
|
||||
|
||||
/*** Public transport elements ***/
|
||||
require($includesDir.'/PTElement.php');
|
||||
require($includesDir.'/PTLine.php');
|
||||
require($includesDir.'/PTStop.php');
|
||||
|
||||
/*** Calculators and helpers ***/
|
||||
require($includesDir.'/DepartureFormatter.php');
|
||||
require($includesDir.'/DelayCalculator.php');
|
||||
|
||||
|
||||
class NotImplementedException extends Exception {}
|
||||
|
||||
|
||||
?>
|
91
htdocs/old/haltebord.css
Normal file
91
htdocs/old/haltebord.css
Normal file
|
@ -0,0 +1,91 @@
|
|||
body {
|
||||
font-family: sans-serif;
|
||||
margin: 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-size: 120%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.info, .footnote {
|
||||
text-align: center;
|
||||
padding: 0 1em;
|
||||
}
|
||||
.info {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
.info {
|
||||
width: 400px;
|
||||
text-align: right;
|
||||
min-width: 30%;
|
||||
max-width: 1000px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.info .stopref {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
table.stopInfoboard {
|
||||
min-width: 30%;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
border-spacing: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.stopInfoboard td {
|
||||
padding: 0.4em 0.1em;
|
||||
}
|
||||
|
||||
@media (min-width:500px) {
|
||||
table.stopInfoboard td {
|
||||
padding: 0.4em;
|
||||
}
|
||||
}
|
||||
|
||||
tr.line.even td {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
tr.line .lineNumber {
|
||||
text-align: right;
|
||||
width: 3em;
|
||||
}
|
||||
tr.line .lineNumber span {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
width: 2em;
|
||||
padding: 0.1em;
|
||||
margin-right: 0.4em;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
tr.line .departure {
|
||||
text-align: right;
|
||||
padding: 0 0.2em;
|
||||
}
|
||||
@media (min-width:500px) {
|
||||
tr.line .departure {
|
||||
padding: 0 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.delay {
|
||||
font-weight: bold;
|
||||
font-size: 90%;
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.theoretical {
|
||||
font-size: 90%;
|
||||
color: #a00;
|
||||
font-family: Impact, fantasy, serif;
|
||||
}
|
27
htdocs/old/index.php
Normal file
27
htdocs/old/index.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="format-detection" content="telephone=no" />
|
||||
<title>Haltebord lite</title>
|
||||
<style>
|
||||
@import url('haltebord.css');
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
require('./main.php');
|
||||
|
||||
$stopRef = '506415';
|
||||
if (isset($_GET['h'])) {
|
||||
$stopRef = $_GET['h'];
|
||||
}
|
||||
|
||||
$infoboard = new StopInfoboard($stopRef);
|
||||
$infoboard->make();
|
||||
|
||||
?>
|
||||
</body>
|
||||
</html>
|
20
htdocs/old/main.php
Normal file
20
htdocs/old/main.php
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
|
||||
$timezone = new DateTimeZone('Europe/Brussels');
|
||||
|
||||
$includesDir = '/mnt/imagestore/rumores.eu/delijnincludes/old/';
|
||||
|
||||
require($includesDir.'/ApiRequest.php');
|
||||
require($includesDir.'/ApiCoreRequest.php');
|
||||
require($includesDir.'/PTElement.php');
|
||||
require($includesDir.'/PTLine.php');
|
||||
require($includesDir.'/PTStop.php');
|
||||
require($includesDir.'/StopInfoboard.php');
|
||||
require($includesDir.'/DepartureFormatter.php');
|
||||
require($includesDir.'/DelayCalculator.php');
|
||||
|
||||
|
||||
class NotImplementedException extends Exception {}
|
||||
|
||||
|
||||
?>
|
18
includes/ApiCoreRequest.php
Normal file
18
includes/ApiCoreRequest.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
class ApiCoreRequest extends ApiRequest {
|
||||
|
||||
protected static $apiName = 'rise-api-core';
|
||||
|
||||
public function __toString () {
|
||||
return 'ApiCoreRequest[action=' . $this->action . ', method=' . $this->method . ']';
|
||||
}
|
||||
|
||||
public function __construct ($action, $method='GET') {
|
||||
|
||||
parent::__construct(static::$apiName, $action, $method);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
92
includes/ApiRequest.php
Normal file
92
includes/ApiRequest.php
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
class ApiRequest {
|
||||
|
||||
protected static $baseURL = 'https://www.delijn.be';
|
||||
|
||||
protected $apiPath;
|
||||
protected $action;
|
||||
protected $url;
|
||||
|
||||
protected $http_response_header;
|
||||
|
||||
public function __toString () {
|
||||
return 'ApiRequest[url=' . $this->url . ']';
|
||||
}
|
||||
|
||||
public function __construct ($apiPath, $action, $method='GET') {
|
||||
|
||||
if (!is_string($action)) {
|
||||
throw new InvalidArgumentException('$action must be a string');
|
||||
}
|
||||
$this->apiPath = $apiPath;
|
||||
$this->action = $action;
|
||||
$this->url = Static::$baseURL.'/'.$apiPath.'/'.$action;
|
||||
|
||||
if (preg_match('~//.*//~',$this->url) === 1) {
|
||||
throw new InvalidArgumentException('Resulting URL ('.$this->url.') contains a double slash');
|
||||
}
|
||||
|
||||
if (!is_string($method)) {
|
||||
throw new InvalidArgumentException('$method must be a string');
|
||||
}
|
||||
switch ($method) {
|
||||
case 'GET': case 'POST': case 'PUT': case 'DELETE': break;
|
||||
throw new InvalidArgumentException('$method must be one of the following: "GET", "POST", "PUT", "DELETE"');
|
||||
}
|
||||
$this->method = $method;
|
||||
|
||||
}
|
||||
|
||||
public function exec ($dataToSend=null) {
|
||||
|
||||
$opts = array('http' =>
|
||||
array(
|
||||
'method' => $this->method
|
||||
)
|
||||
);
|
||||
if (!is_null($dataToSend)) {
|
||||
if (is_array($dataToSend)) {
|
||||
$opts['http']['content'] = http_build_query($dataToSend);
|
||||
} else {
|
||||
throw new InvalidArgumentException('$dataToSend must be either NULL or an array');
|
||||
}
|
||||
}
|
||||
|
||||
$context = stream_context_create($opts);
|
||||
|
||||
$json = @file_get_contents(
|
||||
$this->url, false, $context
|
||||
);
|
||||
|
||||
// Make the HTTP response header available if they want to get it
|
||||
// If there is no network connection, $http_response_header may be undefined
|
||||
if (isset($http_response_header)) {
|
||||
$this->http_response_header = $http_response_header;
|
||||
} else {
|
||||
$this->http_response_header = null;
|
||||
}
|
||||
|
||||
|
||||
$result = json_decode($json, true);
|
||||
|
||||
switch (json_last_error()) {
|
||||
case JSON_ERROR_NONE:
|
||||
return $result;
|
||||
break;
|
||||
case JSON_ERROR_SYNTAX:
|
||||
throw new Exception('Result was not valid JSON: ' . json_last_error_msg());
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Result could not be parsed as JSON: ' . json_last_error_msg());
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public function getHttpResponseHeader () {
|
||||
return $this->http_response_header;
|
||||
}
|
||||
}
|
||||
?>
|
96
includes/ApiRequestDummy.php
Normal file
96
includes/ApiRequestDummy.php
Normal file
File diff suppressed because one or more lines are too long
18
includes/ApiSearchRequest.php
Normal file
18
includes/ApiSearchRequest.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
class ApiSearchRequest extends ApiRequest {
|
||||
|
||||
protected static $apiName = 'rise-api-search';
|
||||
|
||||
public function __toString () {
|
||||
return 'ApiCoreRequest[action=' . $this->action . ', method=' . $this->method . ']';
|
||||
}
|
||||
|
||||
public function __construct ($action, $method='GET') {
|
||||
|
||||
parent::__construct(static::$apiName, $action, $method);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
32
includes/DelayCalculator.php
Normal file
32
includes/DelayCalculator.php
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
class DelayCalculator {
|
||||
|
||||
private $currentTime;
|
||||
|
||||
public function __construct ($currentTime) {
|
||||
|
||||
if (!is_string($currentTime)) {
|
||||
throw new InvalidArgumentException('$currentTime must be a string');
|
||||
}
|
||||
if (
|
||||
( $this->currentTime = new DateTime($currentTime, $GLOBALS['timezone']) ) === false
|
||||
) {
|
||||
throw new InvalidArgumentException('$currentTime must be HH:MM');
|
||||
}
|
||||
#echo PHP_EOL;var_dump($this->currentTime);echo PHP_EOL;
|
||||
|
||||
}
|
||||
|
||||
public function calculateFromRemainingTime (DateInterval $timeToDeparture, DateTime $scheduledTime) {
|
||||
$ct = clone $this->currentTime;
|
||||
return $ct->add($timeToDeparture)->diff($scheduledTime);
|
||||
}
|
||||
|
||||
public function calculateFromExpectedTime (DateTime $departureTime, DateTime $scheduledTime) {
|
||||
return $departureTime->diff($scheduledTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
43
includes/DepartureFormatter.php
Normal file
43
includes/DepartureFormatter.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
class DepartureFormatter {
|
||||
|
||||
//$realdeparturecalendar, $scheduleddeparture,
|
||||
public static function format ($realdeparture, DelayCalculator $delayc) {
|
||||
|
||||
//$scheduleddepartureObj = new DateTime('@'.($scheduleddeparture/1000), $GLOBALS['timezone']);
|
||||
|
||||
//$delay = $realdepartureObj->diff($scheduleddepartureObj);
|
||||
|
||||
|
||||
$realtime = null;
|
||||
|
||||
// Not realtime
|
||||
if ( preg_match('/([12]?\d):([0-5]\d)/', $realdeparture) === 1 ) {
|
||||
$realtime = false;
|
||||
$time = DateTime::createFromFormat("G:i", $realdeparture, $GLOBALS['timezone']);
|
||||
}
|
||||
// Realtime
|
||||
else {
|
||||
$matches = array();
|
||||
if ( preg_match('/(\d+)\'/', $realdeparture, $matches) === 1 ) {
|
||||
$realtime = true;
|
||||
$time = new DateTime("now", $GLOBALS['timezone']);
|
||||
$time->add(new DateInterval("PT".$matches[1]."M"));
|
||||
}
|
||||
}
|
||||
|
||||
//$scheduleddepartureObj->setTimezone($GLOBALS['timezone']);
|
||||
return array(
|
||||
//$scheduleddepartureObj->format('G:i'),
|
||||
$time->format('G:i'),
|
||||
"+0",
|
||||
//$delay->format('%R%i'),
|
||||
$realtime
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
25
includes/HTMLTools.php
Normal file
25
includes/HTMLTools.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
class HTMLTools {
|
||||
|
||||
private static $invisibleSpace = '<span class="invisiblespace"> </span>';
|
||||
|
||||
public static function makeSafe ($string) {
|
||||
|
||||
return htmlentities($string);
|
||||
|
||||
}
|
||||
|
||||
public static function makeSafeAndWrapBetter ($string) {
|
||||
|
||||
return preg_replace(
|
||||
array('~/|-|\.~'),
|
||||
array(static::$invisibleSpace.'$0'.static::$invisibleSpace), // Put an invisible space before and after each slash, hyphen and period
|
||||
static::makeSafe($string)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
10
includes/Infoboard.php
Normal file
10
includes/Infoboard.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
abstract class Infoboard extends UI {
|
||||
|
||||
protected static $theoreticalBefore = '<span class="theoretical">+</span>';
|
||||
protected static $theoreticalAfter = '<span class="theoretical">+</span>';
|
||||
|
||||
}
|
||||
|
||||
?>
|
19
includes/LineInfoboard.php
Normal file
19
includes/LineInfoboard.php
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
class LineInfoboard extends Infoboard {
|
||||
|
||||
public function title () {
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
public function display () {
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
54
includes/PTElement.php
Normal file
54
includes/PTElement.php
Normal file
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
abstract class PTElement {
|
||||
|
||||
const UNKNOWN = 1;
|
||||
const TRAM = 1;
|
||||
const BUS = 2;
|
||||
const BELBUS = 4;
|
||||
|
||||
protected $ref;
|
||||
protected $publicRef;
|
||||
|
||||
protected $infoFetched = false;
|
||||
|
||||
public function __construct ($ref) {
|
||||
|
||||
if (!is_int($ref)) {
|
||||
throw new InvalidArgumentException('$ref must be an integer');
|
||||
}
|
||||
$this->ref = $ref;
|
||||
|
||||
}
|
||||
|
||||
public function __toString () {
|
||||
return 'PTElement[' . $this->ref . ']';
|
||||
}
|
||||
|
||||
public function getRef () {
|
||||
return $this->ref;
|
||||
}
|
||||
|
||||
protected abstract function fetchInfo ();
|
||||
|
||||
|
||||
public static function lineTypeTextToConst ($lineTypeText) {
|
||||
switch ($lineTypeText) {
|
||||
case 'tram';
|
||||
return static::TRAM;
|
||||
break;
|
||||
case 'bus';
|
||||
return static::BUS;
|
||||
break;
|
||||
case 'belbus';
|
||||
return static::BELBUS;
|
||||
break;
|
||||
default;
|
||||
return static::UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
79
includes/PTLine.php
Normal file
79
includes/PTLine.php
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
class PTLine extends PTElement {
|
||||
|
||||
protected $entity;
|
||||
protected $direction;
|
||||
|
||||
protected $lineType;
|
||||
protected $publicRef;
|
||||
protected $directionDesc;
|
||||
|
||||
public function __construct ($entity, $ref, $direction) {
|
||||
|
||||
parent::__construct($ref);
|
||||
|
||||
if (!is_int($entity)) {
|
||||
throw new InvalidArgumentException('$entity must be an integer');
|
||||
}
|
||||
$this->entity = $entity;
|
||||
|
||||
if (!is_int($direction)) {
|
||||
throw new InvalidArgumentException('$direction must be an integer');
|
||||
}
|
||||
$this->direction = $direction;
|
||||
|
||||
}
|
||||
|
||||
public function __toString () {
|
||||
return 'PTLine[' . $this->entity . '/' . $this->ref . '/' . $this->direction . ']';
|
||||
}
|
||||
|
||||
public function getRef () {
|
||||
return $this->ref;
|
||||
}
|
||||
|
||||
public function getPublicRef () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->publicRef;
|
||||
}
|
||||
public function getLineType () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->lineType;
|
||||
}
|
||||
public function getDirectionDesc () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->directionDesc;
|
||||
}
|
||||
|
||||
protected function fetchInfo () {
|
||||
|
||||
$apireq = new ApiCoreRequest('lijnen/titel/' . $this->entity . '/' . $this->ref . '/' . $this->direction);
|
||||
$response = $apireq->exec();
|
||||
|
||||
$this->lineType = PTElement::lineTypeTextToConst($response['lijnType']);
|
||||
$this->publicRef = $response['lijnNummerPubliek'];
|
||||
$this->directionDesc = $response['lijnRichting'];
|
||||
|
||||
}
|
||||
|
||||
public function getTimetable () {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public function getTimetableAtStop (PTStop $stop) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
||||
public static function htmlElement($bgColor, $bgBorder, $fgColor, $lineNumber, $class='') {
|
||||
return '<span class="line-nr ' . $class . '" style="' .
|
||||
'background:' . HTMLTools::makeSafe($bgColor) . ';' .
|
||||
'border-color:' . HTMLTools::makeSafe($bgBorder) . ';' .
|
||||
'color:' . HTMLTools::makeSafe($fgColor) . ';' .
|
||||
'">' .$lineNumber . '</span>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
59
includes/PTStop.php
Normal file
59
includes/PTStop.php
Normal file
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
|
||||
class PTStop extends PTElement {
|
||||
|
||||
protected $exists;
|
||||
protected $municipality;
|
||||
protected $name;
|
||||
protected $fullName;
|
||||
protected $location;
|
||||
|
||||
public function __toString () {
|
||||
return 'PTStop[' . $this->ref . ']';
|
||||
}
|
||||
|
||||
public function getExists () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->exists;
|
||||
}
|
||||
public function getMunicipality () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->municipality;
|
||||
}
|
||||
public function getName () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->name;
|
||||
}
|
||||
public function getFullName () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->fullName;
|
||||
}
|
||||
public function getLocation () {
|
||||
if (!$this->infoFetched) $this->fetchInfo();
|
||||
return $this->location;
|
||||
}
|
||||
|
||||
protected function fetchInfo () {
|
||||
|
||||
$apireq = new ApiCoreRequest('haltes/titel/' . $this->ref);
|
||||
$response = $apireq->exec();
|
||||
|
||||
$this->exists = !is_null($response);
|
||||
|
||||
$this->municipality = $response['omschrijvingGemeente'];
|
||||
$this->name = $response['omschrijvingKort'];
|
||||
$this->fullName = $response['omschrijvingLang'];
|
||||
$this->location = array(floatval($response['coordinaat']['lt']), floatval($response['coordinaat']['ln']));
|
||||
|
||||
}
|
||||
|
||||
public function getImminentVehicles ($numberOfLines) {
|
||||
|
||||
$apireq = new ApiCoreRequest('haltes/doorkomstenditmoment/' . $this->ref . '/' . $numberOfLines);
|
||||
return $apireq->exec();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
86
includes/ResultsInterface.php
Normal file
86
includes/ResultsInterface.php
Normal file
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
class ResultsInterface extends UI {
|
||||
|
||||
private $query;
|
||||
private $stops;
|
||||
|
||||
public function __construct($searchQuery, $searchResults) {
|
||||
|
||||
$this->query = $searchQuery;
|
||||
$this->stops = $searchResults['haltes'];
|
||||
|
||||
}
|
||||
|
||||
public function title () {
|
||||
|
||||
return 'Zoekresultaten';
|
||||
|
||||
}
|
||||
|
||||
public function display() {
|
||||
|
||||
parent::header();
|
||||
|
||||
echo '<form class="titlesearch">';
|
||||
|
||||
echo '<h2>Zoeken naar halte <input type="text" name="h" value="' .
|
||||
HTMLTools::makeSafe($this->query) .
|
||||
'" id="stop-searchfield"></input><input type="submit" value="Zoek"></input></h2>';
|
||||
|
||||
echo '</form>';
|
||||
|
||||
if (isset($this->stops[0])) {
|
||||
|
||||
echo '<div class="search-results">';
|
||||
|
||||
foreach ($this->stops as $stop) {
|
||||
|
||||
echo '<a href="?h=' . rawurlencode($stop['halteNummer']) . '" class="result stop">';
|
||||
|
||||
echo '<span class="name">' . $stop['omschrijvingLang'] . '</span> ';
|
||||
echo '<span class="ref">(' . $stop['halteNummer'] . ')</span>';
|
||||
if (isset($stop['bestemmingen'][0])) {
|
||||
echo '<span class="dest"><span class="deemphasize">richting</span> ' . parent::listify($stop['bestemmingen']) . '</span>';
|
||||
} else {
|
||||
echo '<span class="dest deemphasize">richting onbekend</span>';
|
||||
}
|
||||
echo '<span class="lines">';
|
||||
|
||||
if (isset($stop['lijnen'][0])) {
|
||||
|
||||
foreach ($stop['lijnen'] as $line) {
|
||||
echo PTLine::htmlElement(
|
||||
$line['kleurAchterGrond'],
|
||||
$line['kleurAchterGrondRand'],
|
||||
$line['kleurVoorGrond'],
|
||||
$line['lijnNummerPubliek'],
|
||||
'small');
|
||||
echo ' ';
|
||||
}
|
||||
|
||||
} else {
|
||||
echo '<span class="not-served-msg">niet bediend</span>';
|
||||
}
|
||||
|
||||
echo '</span>';
|
||||
|
||||
echo '</a>';
|
||||
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
} else {
|
||||
|
||||
echo '<div class="user-error">Geen resultaten</div>';
|
||||
|
||||
}
|
||||
|
||||
parent::footer();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
38
includes/SearchQuery.php
Normal file
38
includes/SearchQuery.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
define('SEARCH_STOPS',1);
|
||||
define('SEARCH_LINES',2);
|
||||
define('SEARCH_ALL',SEARCH_STOPS|SEARCH_LINES);
|
||||
|
||||
class SearchQuery {
|
||||
|
||||
private $originalQueryString;
|
||||
private $queryString;
|
||||
private $searchForTypes;
|
||||
|
||||
public function __construct ($queryString, $searchForTypes=SEARCH_ALL) {
|
||||
|
||||
if (!is_string($queryString)) {
|
||||
throw new InvalidArgumentException('$queryString must be a string');
|
||||
}
|
||||
if (!is_int($searchForTypes)) {
|
||||
throw new InvalidArgumentException('$searchForTypes must be an integer (a bitwise OR-combination of SEARCH_...)');
|
||||
}
|
||||
|
||||
$this->originalQueryString = $queryString;
|
||||
$this->queryString = rawurlencode(strtolower(str_replace(array('"', "'", '-', '.', '%'), ' ', $queryString)));
|
||||
$this->searchForTypes = $searchForTypes;
|
||||
|
||||
}
|
||||
//https://www.delijn.be/rise-api-search/search/lijnen/knokke/1
|
||||
|
||||
public function execute () {
|
||||
|
||||
$req = new ApiSearchRequest('search/haltes/' . $this->queryString . '/1');
|
||||
return $req->exec();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
31
includes/SearchUI.php
Normal file
31
includes/SearchUI.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
class SearchUI extends UI {
|
||||
|
||||
public function title () {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
public function display () {
|
||||
|
||||
parent::header();
|
||||
|
||||
echo '<h2>Zoek halte</h2>';
|
||||
echo '<form class="mainsearch">';
|
||||
echo '<div class="inputlabel"><label for="stop-searchfield">Naam of haltenummer:</label></div>';
|
||||
echo '<input type="text" name="h" id="stop-searchfield"/><input type="submit" value="Zoek"/>';
|
||||
echo '</form>';
|
||||
|
||||
/* echo '<h2>Zoek lijn</h2>';
|
||||
echo '<form class="mainsearch">';
|
||||
echo '<div class="inputlabel"><label for="line-searchfield">Bestemming of lijnnummer:</label></div>';
|
||||
echo '<input type="text" name="l" id="line-searchfield"/><input type="submit" value="Zoek"/>';
|
||||
echo '</form>';*/
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
237
includes/StopInfoboard.php
Normal file
237
includes/StopInfoboard.php
Normal file
|
@ -0,0 +1,237 @@
|
|||
<?php
|
||||
|
||||
function compareDoorkomsten ($d1, $d2) {
|
||||
$t1 = $d1['vertrekTheoretischeTijdstip'];
|
||||
if (!empty($d1['vertrekRealtimeTijdstip'])) {
|
||||
$t1 = $d1['vertrekRealtimeTijdstip'];
|
||||
}
|
||||
|
||||
$t2 = $d2['vertrekTheoretischeTijdstip'];
|
||||
if (!empty($d2['vertrekRealtimeTijdstip'])) {
|
||||
$t2 = $d2['vertrekRealtimeTijdstip'];
|
||||
}
|
||||
|
||||
return $t1 - $t2;
|
||||
}
|
||||
|
||||
function formatDelay ($delay) {
|
||||
$early = $delay < 0;
|
||||
$totalSeconds = abs($delay);
|
||||
|
||||
$totalMinutes = round($totalSeconds / 60);
|
||||
|
||||
$hours = intdiv($totalMinutes, 60);
|
||||
$minutes = $totalMinutes % 60;
|
||||
|
||||
$str = ($hours !== 0 ? $hours . 'h' : '') . ($minutes !== 0 ? $minutes . 'm' : '');
|
||||
//return ($delay > 0 ? '+' : '-') . $str;
|
||||
return $str . ($delay > 0 ? ' te laat' : ' te vroeg');
|
||||
}
|
||||
|
||||
class StopInfoboard extends Infoboard {
|
||||
|
||||
private $found = false;
|
||||
|
||||
private $stop;
|
||||
private $numberOfLines;
|
||||
|
||||
private $currentTime;
|
||||
|
||||
private $lines;
|
||||
|
||||
private $disturbed = false;
|
||||
private $allLinesDisturbed = false;
|
||||
private $disturbances = false;
|
||||
private $notServed = false;
|
||||
|
||||
public function __construct ($stopRef, $numberOfLines=50) {
|
||||
global $timezone;
|
||||
|
||||
$this->currentTime = new DateTime('now', $timezone);
|
||||
|
||||
$this->stop = new PTStop(intval($stopRef));
|
||||
$this->numberOfLines = $numberOfLines;
|
||||
|
||||
$result = $this->stop->getImminentVehicles($numberOfLines);
|
||||
|
||||
$this->detours = $result['halteOmleidingen'];
|
||||
$this->disturbed = $result['dienstRegelingVerstoord'];
|
||||
$this->allLinesDisturbed = $result['alleLijnenVerstoord'];
|
||||
$this->disturbances = $result['storingen'];
|
||||
$this->notServed = $result['nietBediend'];
|
||||
|
||||
$this->lines = $result['lijnen'];
|
||||
|
||||
}
|
||||
|
||||
public function title() {
|
||||
|
||||
$name = $this->stop->getFullName();
|
||||
if ($name) return $name;
|
||||
|
||||
return 'Halte';
|
||||
|
||||
}
|
||||
|
||||
public function display() {
|
||||
global $timezone;
|
||||
|
||||
parent::header();
|
||||
|
||||
if (!$this->stop->getExists()) {
|
||||
|
||||
echo '<div class="user-error">De halte met haltenummer ' . HTMLTools::makeSafe($this->stop->getRef()) . ' werd niet gevonden.</div>';
|
||||
|
||||
parent::footer();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
echo '<h2>' . HTMLTools::makeSafe($this->stop->getFullName()) . '</h2>';
|
||||
|
||||
echo '<div class="info">';
|
||||
echo '<div class="stopref">Haltenummer ' . HTMLTools::makeSafe($this->stop->getRef()) . '</div>';
|
||||
echo '<div class="lastrefreshed">Info van ' . $this->currentTime->format('H:i') . '<span class="seconds">:' . $this->currentTime->format('s') . '</span></div>';
|
||||
echo '</div>';
|
||||
|
||||
if (!empty($this->disturbances)) {
|
||||
echo '<div class="disturbance"><h3>Storingen en mededelingen</h3><ul>';
|
||||
foreach ($this->disturbances as $disturbance) {
|
||||
echo '<li>' . HTMLTools::makeSafe($disturbance) . '</li>';
|
||||
}
|
||||
echo '</ul></div>';
|
||||
}
|
||||
if (!empty($this->detours)) {
|
||||
echo '<div class="disturbance"><h3>Omleidingen</h3><ul>';
|
||||
foreach ($this->detours as $detour) {
|
||||
$description = $detour['omleidingen'][0];
|
||||
echo '<li><h4>' . HTMLTools::makeSafe($description['title']) . '</h4><p>' . HTMLTools::makeSafe($description['omleiding']) . '</p>';
|
||||
|
||||
if (!empty($detour['verstoordeLijnenSet'])) {
|
||||
echo '<p class="affectedLines">';
|
||||
foreach ($detour['verstoordeLijnenSet'] as $line) {
|
||||
echo PTLine::htmlElement(
|
||||
$line['kleurAchterGrond'],
|
||||
$line['kleurAchterGrondRand'],
|
||||
$line['kleurVoorGrond'],
|
||||
$line['lijnNummerPubliek']);
|
||||
echo ' ';
|
||||
}
|
||||
echo '</p>';
|
||||
}
|
||||
echo '</li>';
|
||||
}
|
||||
echo '</ul></div>';
|
||||
}
|
||||
if ($this->notServed) {
|
||||
echo '<div class="disturbance">Deze halte wordt momenteel niet bediend.</div>';
|
||||
} elseif ($this->allLinesDisturbed) {
|
||||
echo '<div class="disturbance">De dienstregeling van alle lijnen aan deze halte is verstoord.</div>';
|
||||
} elseif ($this->disturbed) {
|
||||
echo '<div class="disturbance">De dienstregeling van sommige lijnen aan deze halte is verstoord.</div>';
|
||||
}
|
||||
|
||||
if (empty($this->lines)) {
|
||||
echo '<div class="stopInfoboard noLines">Geen doorkomsten in de nabije toekomst</div>';
|
||||
} else {
|
||||
|
||||
$anyNotRealtime = false;
|
||||
|
||||
echo '<table class="stopInfoboard" border="0">';
|
||||
|
||||
$evenrow = true;
|
||||
|
||||
usort($this->lines, compareDoorkomsten);
|
||||
|
||||
foreach ($this->lines as $line) {
|
||||
|
||||
$scheduledTime = intdiv($line['vertrekTheoretischeTijdstip'], 1000);
|
||||
$realtimeTime = intdiv($line['vertrekRealtimeTijdstip'], 1000);
|
||||
if ($realtimeTime == 0) $realtimeTime = null;
|
||||
|
||||
$realtime = !is_null($realtimeTime);
|
||||
if (!$realtime) $anyNotRealtime = true;
|
||||
|
||||
$timeDT = new DateTime('now', $timezone);
|
||||
if ($realtime) {
|
||||
$timeDT->setTimestamp($realtimeTime);
|
||||
} else {
|
||||
$timeDT->setTimestamp($scheduledTime);
|
||||
}
|
||||
$delay = $realtime ? $realtimeTime - $scheduledTime : 0;
|
||||
|
||||
$canceled = in_array('DELETED', $line['predictionStatussen']) || in_array('CANCELLED', $line['predictionStatussen']);
|
||||
|
||||
|
||||
echo '<tr class="line' . ($evenrow?' even':' odd') . ($canceled?' canceled':'') . '">';
|
||||
|
||||
// Line number
|
||||
echo '<td class="lineNumber">' . PTLine::htmlElement(
|
||||
$line['kleurAchterGrond'],
|
||||
$line['kleurAchterGrondRand'],
|
||||
$line['kleurVoorGrond'],
|
||||
$line['lijnNummerPubliek']) . '</td> ';
|
||||
|
||||
// Destination
|
||||
echo '<td class="destination">';
|
||||
if ($canceled) echo '<del>';
|
||||
echo HTMLTools::makeSafeAndWrapBetter($line['bestemming']);
|
||||
if ($canceled) echo '</del>';
|
||||
echo '</td>';
|
||||
|
||||
// Delay
|
||||
echo '<td class="delay ' . ($delay < 0 ? 'early' : '') . '">';
|
||||
if ($canceled) {
|
||||
echo 'Rijdt niet';
|
||||
} elseif (abs($delay) >= 60) {
|
||||
echo formatDelay($delay) . ':';
|
||||
}
|
||||
echo '</td>';
|
||||
|
||||
// Departure time
|
||||
echo '<td class="departureH ' . ($realtime ? 'rt' : 'th') . '">';
|
||||
|
||||
if (!$realtime) {
|
||||
echo static::$theoreticalBefore;
|
||||
}
|
||||
|
||||
echo $timeDT->format("H");
|
||||
|
||||
echo '</td>';
|
||||
echo '<td class="departureSep">:</td>';
|
||||
echo '<td class="departureMS ' . ($realtime ? 'rt' : 'th') . '">';
|
||||
|
||||
echo $timeDT->format("i");
|
||||
|
||||
if ($realtime && intval($timeDT->format('s')) !== 0) {
|
||||
echo '<span class="seconds">:' . $timeDT->format('s') . '</span>';
|
||||
}
|
||||
|
||||
if (!$realtime) {
|
||||
echo static::$theoreticalAfter;
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
$evenrow = !$evenrow;
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
|
||||
if ($anyNotRealtime) {
|
||||
echo '<div class="footnote">' . static::$theoreticalBefore . 'Theoretische vertrektijd' . static::$theoreticalAfter . '</div>';
|
||||
}
|
||||
}
|
||||
|
||||
$coords = $this->stop->getLocation();
|
||||
echo '<a href="geo:' . $coords[0] . ',' . $coords[1] . '?z=17">Locatie van halte</a>';
|
||||
|
||||
parent::footer();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
57
includes/UI.php
Normal file
57
includes/UI.php
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
abstract class UI {
|
||||
|
||||
abstract public function title();
|
||||
abstract public function display();
|
||||
|
||||
protected function header() {
|
||||
echo '<div class="header">';
|
||||
echo '<h1><a href="?">De Lijn Reisinformatie lite</a></h1> ';
|
||||
echo '<div class="subtitle">(niet-officieel)</div>';
|
||||
echo '</div>';
|
||||
|
||||
}
|
||||
|
||||
protected function footer() {
|
||||
|
||||
echo '<div class="bottom-search">';
|
||||
echo '<h2>Zoek iets anders</h2>';
|
||||
echo '<div><form>';
|
||||
echo '<label for="stop-searchfield">Zoek halte:</label> <input type="text" name="h" id="stop-searchfield"></input><input type="submit" value="Zoek"></input>';
|
||||
// echo '</form></div><div><form>';
|
||||
// echo '<label for="line-searchfield">Zoek lijn:</label> <input type="text" name="l" id="line-searchfield"></input><input type="submit" value="Zoek"></input>';
|
||||
echo '</form></div>';
|
||||
echo '</div>';
|
||||
|
||||
}
|
||||
|
||||
public function listify($array) {
|
||||
|
||||
$listString = '';
|
||||
|
||||
$length = count($array);
|
||||
|
||||
switch ($length) {
|
||||
case 0:
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
return HTMLTools::makeSafeAndWrapBetter($array[0]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return HTMLTools::makeSafeAndWrapBetter($array[0]) . ' <span class="deemphasize">en</span> ' . HTMLTools::makeSafeAndWrapBetter($array[1]);
|
||||
break;
|
||||
|
||||
default:
|
||||
return HTMLTools::makeSafeAndWrapBetter($array[0]) . '<span class="deemphasize">,</span> ' . HTMLTools::makeSafeAndWrapBetter($array[1]) . '<span class="deemphasize">...</span>';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
1
omleiding.json
Normal file
1
omleiding.json
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue