Prepare code for Eurostar/Trenitalia France/RENFE/ÖBB data input
5
sncf-station/public/bus.svg
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="white" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.384 5.25c.008-.04.068-.308.22-.672h19.792c.152.362.213.626.218.663 1.047 4.827 1.612 9.395 1.696 13.604H5.69c.079-4.201.65-8.774 1.694-13.596zm19.178 22.7c-1.398 0-2.532-1.082-2.532-2.418s1.134-2.418 2.532-2.418c1.4 0 2.532 1.082 2.532 2.418s-1.133 2.418-2.532 2.418zm-18.313 0c-1.4 0-2.53-1.082-2.53-2.418s1.13-2.418 2.53-2.418c1.398 0 2.534 1.082 2.534 2.418S9.647 27.95 8.25 27.95zM4.223 10.5c-1.636 11.16-.15 17.16-.076 17.452.186 1.014.67 1.607 1.45 1.82.004.804.006 3.44.006 3.44 0 .987.842 1.788 1.878 1.788h1.467c1.033 0 1.877-.8 1.877-1.789l-.008-3.336H23.91v3.333c0 .989.842 1.792 1.872 1.792l1.746-.005c.97 0 1.601-.7 1.601-1.787v-3.45c.923-.243 1.61-.935 1.741-1.881l-.013.07c.048-.186.692-2.77.692-7.608 0-2.624-.193-5.909-.766-9.836.29.216.665.322 1.055.263.75-.112 1.265-.787 1.146-1.503l-.407-2.456c-.119-.718-.823-1.207-1.573-1.094a1.378 1.378 0 0 0-.946.6c-.11-.56-.224-1.128-.35-1.706V4.6C29.39 3.013 27.735.019 23.736.005H20.68L11.272 0c-4.01.013-5.66 3.022-5.974 4.608-.129.58-.242 1.147-.352 1.707A1.373 1.373 0 0 0 4 5.713c-.75-.113-1.457.376-1.576 1.094l-.407 2.456c-.119.716.397 1.391 1.15 1.503.388.059.767-.05 1.056-.266z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
15
sncf-station/public/eurostar.svg
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg version="1.0" width="1140.000000pt" height="260.000000pt" viewBox="0 0 1140.000000 260.000000" preserveAspectRatio="xMidYMid meet" id="svg22" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs id="defs26"/>
|
||||
<g transform="translate(0.000000,260.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none" id="g20" style="fill:#116bfe;fill-opacity:1">
|
||||
<path d="M1085 2579 c-194 -28 -429 -132 -592 -261 -499 -395 -632 -1129 -306 -1686 186 -318 511 -543 877 -607 128 -22 369 -20 493 4 375 73 671 296 852 642 66 125 124 301 133 399 2 30 0 35 -17 32 -32 -6 -41 -21 -78 -134 -44 -132 -88 -220 -162 -323 -181 -254 -444 -425 -742 -481 -135 -25 -385 -15 -513 21 -382 106 -686 398 -803 770 -40 128 -50 216 -44 387 7 221 56 383 169 566 63 101 232 279 327 342 396 264 889 269 1284 11 146 -96 305 -270 387 -425 17 -32 29 -61 27 -62 -3 -4 -537 -199 -830 -305 l-108 -39 -9 23 c-5 12 -23 180 -40 372 -17 193 -33 358 -36 368 -3 9 -14 17 -24 17 -21 0 -22 -5 -45 -260 -38 -407 -48 -505 -54 -512 -4 -4 -159 35 -346 87 -298 83 -342 93 -355 80 -9 -9 -11 -18 -5 -24 6 -5 133 -71 283 -146 149 -75 272 -141 272 -146 0 -5 -124 -71 -275 -146 -194 -97 -275 -143 -275 -154 0 -9 6 -19 13 -22 6 -2 156 35 332 84 176 49 330 89 341 89 19 0 22 -7 28 -77 7 -85 28 -302 51 -536 8 -81 15 -150 15 -153 0 -3 10 -4 22 -2 22 3 23 10 60 383 20 209 37 381 37 383 4 12 33 5 528 -134 89 -25 167 -43 173 -39 29 18 -14 47 -265 175 -148 76 -270 144 -270 150 0 6 192 105 427 219 235 114 434 213 441 220 13 10 13 18 2 54 -25 85 -77 193 -130 272 -179 270 -466 457 -795 519 -90 18 -351 20 -455 5z" id="path2" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M9060 2026 c-38 -62 -162 -169 -242 -208 -63 -31 -162 -61 -275 -84 -13 -2 -23 -11 -23 -19 0 -12 16 -15 79 -15 44 0 82 -4 85 -9 3 -5 -3 -35 -13 -67 -10 -33 -30 -102 -46 -154 -15 -52 -31 -108 -36 -125 -96 -312 -103 -422 -31 -498 50 -54 98 -71 193 -72 79 0 91 3 160 37 100 50 249 195 249 242 0 14 -10 11 -49 -18 -108 -80 -197 -98 -245 -50 -44 45 -40 68 74 449 23 77 48 164 56 194 8 29 17 58 20 62 3 5 70 9 148 9 141 0 144 0 150 23 15 58 18 57 -134 57 -77 0 -140 3 -140 8 0 4 18 63 40 132 22 69 40 128 40 133 0 4 -9 7 -19 7 -11 0 -28 -15 -41 -34z" id="path4" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M3654 1800 c-122 -18 -274 -91 -362 -174 -91 -85 -163 -224 -182 -349 -37 -249 89 -444 317 -492 232 -49 455 46 604 258 27 39 49 74 49 79 0 18 -24 6 -73 -37 -29 -25 -85 -62 -125 -82 -64 -32 -85 -37 -163 -41 -80 -4 -94 -2 -141 22 -91 45 -131 126 -132 261 0 193 114 424 238 485 23 11 54 20 68 20 30 0 73 -32 92 -68 23 -44 25 -226 4 -255 -8 -10 -77 -35 -173 -63 -258 -74 -244 -83 131 -84 160 0 292 4 307 9 21 8 28 20 37 68 16 75 7 189 -18 246 -68 153 -255 230 -478 197z" id="path6" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M6087 1800 c-108 -28 -197 -102 -336 -283 -45 -59 -87 -105 -92 -101 -11 7 -19 -7 113 191 59 90 108 165 108 168 0 3 -76 5 -169 5 -153 0 -170 -2 -175 -17 -12 -43 -236 -950 -236 -956 0 -4 70 -7 155 -7 l154 0 10 38 c6 20 35 136 65 258 61 245 80 300 131 379 63 99 164 147 232 111 36 -18 43 -33 43 -89 0 -50 -37 -133 -91 -204 -39 -53 -38 -74 3 -52 121 64 288 211 329 290 34 66 33 154 -3 201 -15 19 -42 42 -61 51 -43 21 -131 29 -180 17z" id="path8" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M6900 1803 c-77 -9 -165 -35 -238 -70 -107 -52 -225 -169 -275 -273 -102 -210 -83 -434 47 -564 186 -186 577 -157 798 59 104 101 169 239 183 390 8 85 -13 198 -49 259 -60 103 -173 175 -303 195 -71 11 -96 11 -163 4z m143 -77 c57 -35 77 -133 58 -281 -17 -127 -75 -343 -114 -428 -60 -130 -153 -200 -241 -183 -113 23 -141 143 -91 390 65 322 139 469 256 513 36 13 101 8 132 -11z" id="path10" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M7922 1800 c-224 -31 -351 -143 -354 -312 -1 -46 5 -74 20 -104 40 -79 99 -118 381 -252 30 -14 71 -42 93 -62 33 -33 38 -42 38 -83 0 -39 -6 -53 -35 -85 -41 -46 -90 -63 -184 -63 -82 0 -127 17 -165 62 -25 29 -28 39 -24 89 3 39 12 67 31 95 15 22 27 43 27 47 0 5 -65 8 -145 8 l-144 0 -12 -42 c-35 -133 53 -254 221 -305 78 -24 301 -23 390 1 194 53 310 172 310 318 0 134 -77 200 -390 335 -133 58 -173 154 -99 238 35 40 81 57 149 57 119 -1 196 -92 169 -197 -6 -22 -13 -50 -16 -63 l-5 -23 133 3 134 3 3 42 c8 113 -108 240 -255 278 -71 19 -195 25 -271 15z" id="path12" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M9775 1799 c-224 -29 -363 -132 -381 -282 l-7 -57 162 0 161 0 0 73 c1 137 52 199 172 205 80 5 118 -8 154 -52 25 -29 26 -35 21 -111 -4 -62 -27 -163 -42 -182 -1 -2 -95 -17 -210 -33 -246 -36 -281 -44 -360 -81 -152 -71 -225 -192 -195 -324 21 -94 84 -153 187 -176 71 -16 177 -2 253 34 74 35 185 130 239 206 25 33 50 61 58 61 7 0 13 -3 13 -6 0 -3 -34 -62 -75 -131 -41 -68 -75 -128 -75 -134 0 -5 67 -9 163 -9 l162 0 58 228 c89 345 99 391 99 467 3 227 -217 347 -557 304z m211 -511 c-10 -51 -82 -194 -122 -243 -111 -137 -328 -100 -300 50 10 50 67 109 140 145 62 30 221 78 265 79 21 1 23 -2 17 -31z" id="path14" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M11092 1790 c-29 -10 -68 -28 -87 -40 -44 -27 -154 -146 -230 -248 -33 -45 -66 -81 -74 -82 -20 0 -12 15 99 180 56 83 104 158 107 166 4 12 -21 14 -164 14 l-168 0 -119 -477 c-66 -263 -121 -484 -124 -491 -3 -10 29 -12 154 -10 l159 3 66 265 c74 294 105 375 174 449 76 81 173 103 221 50 41 -46 10 -168 -69 -272 -66 -86 -46 -89 71 -11 113 76 222 180 255 246 91 180 -67 332 -271 258z" id="path16" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
<path d="M4288 1428 c-103 -418 -102 -414 -88 -484 27 -131 154 -194 326 -165 132 23 257 108 364 246 40 52 60 67 60 45 0 -5 -34 -65 -75 -132 -41 -67 -75 -126 -75 -130 0 -4 74 -8 163 -8 l164 0 118 478 c65 262 120 483 123 490 3 10 -29 12 -154 10 l-158 -3 -8 -30 c-5 -16 -35 -142 -68 -279 -67 -276 -95 -347 -167 -424 -58 -62 -120 -91 -190 -92 -41 0 -58 5 -80 24 -25 21 -28 31 -26 78 0 29 37 198 82 375 45 178 81 329 81 338 0 13 -23 15 -153 15 l-152 0 -87 -352z" id="path18" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
7
sncf-station/public/eurostar_mini.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg version="1.0" width="260.000000pt" height="260.000000pt" viewBox="0 0 260.000000 260.000000" preserveAspectRatio="xMidYMid meet" id="svg22" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs id="defs26"/>
|
||||
<g transform="translate(0.000000,260.000000) scale(0.100000,-0.100000)" fill="#000000" stroke="none" id="g20" style="fill:#116bfe;fill-opacity:1">
|
||||
<path d="M1085 2579 c-194 -28 -429 -132 -592 -261 -499 -395 -632 -1129 -306 -1686 186 -318 511 -543 877 -607 128 -22 369 -20 493 4 375 73 671 296 852 642 66 125 124 301 133 399 2 30 0 35 -17 32 -32 -6 -41 -21 -78 -134 -44 -132 -88 -220 -162 -323 -181 -254 -444 -425 -742 -481 -135 -25 -385 -15 -513 21 -382 106 -686 398 -803 770 -40 128 -50 216 -44 387 7 221 56 383 169 566 63 101 232 279 327 342 396 264 889 269 1284 11 146 -96 305 -270 387 -425 17 -32 29 -61 27 -62 -3 -4 -537 -199 -830 -305 l-108 -39 -9 23 c-5 12 -23 180 -40 372 -17 193 -33 358 -36 368 -3 9 -14 17 -24 17 -21 0 -22 -5 -45 -260 -38 -407 -48 -505 -54 -512 -4 -4 -159 35 -346 87 -298 83 -342 93 -355 80 -9 -9 -11 -18 -5 -24 6 -5 133 -71 283 -146 149 -75 272 -141 272 -146 0 -5 -124 -71 -275 -146 -194 -97 -275 -143 -275 -154 0 -9 6 -19 13 -22 6 -2 156 35 332 84 176 49 330 89 341 89 19 0 22 -7 28 -77 7 -85 28 -302 51 -536 8 -81 15 -150 15 -153 0 -3 10 -4 22 -2 22 3 23 10 60 383 20 209 37 381 37 383 4 12 33 5 528 -134 89 -25 167 -43 173 -39 29 18 -14 47 -265 175 -148 76 -270 144 -270 150 0 6 192 105 427 219 235 114 434 213 441 220 13 10 13 18 2 54 -25 85 -77 193 -130 272 -179 270 -466 457 -795 519 -90 18 -351 20 -455 5z" id="path2" style="fill:#FCF5D8;fill-opacity:1"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
18
sncf-station/public/frecciarossa.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0.00 0.00 2244.00 378.00">
|
||||
<path fill="#e41c39" d=" M 1374.31 0.00 L 1778.81 0.00 C 1829.24 0.91 1881.04 4.11 1929.49 15.53 C 1993.49 30.62 2053.11 64.39 2103.31 105.20 C 2142.17 136.79 2173.33 159.00 2208.45 185.82 C 2221.50 195.79 2239.69 209.40 2244.00 223.57 L 2244.00 228.90 Q 2240.70 236.11 2231.46 238.97 C 2213.75 244.45 2196.00 245.52 2177.99 245.48 C 2129.56 245.39 2086.47 225.72 2046.36 200.37 C 2010.11 177.46 1969.60 147.19 1940.81 126.94 C 1892.18 92.73 1840.25 62.02 1783.77 42.71 Q 1726.85 23.26 1668.94 19.58 Q 1658.41 18.91 1619.94 17.54 Q 1495.78 13.11 1372.18 0.63 Q 1371.95 0.60 1372.03 0.38 Q 1372.09 0.22 1372.24 0.25 Q 1373.50 0.45 1374.31 0.00 Z"/>
|
||||
<path fill="#212733" d=" M 1200.44 115.44 C 1222.72 90.95 1256.33 84.12 1288.49 88.49 C 1313.77 91.92 1325.14 107.52 1318.08 132.66 C 1302.64 187.61 1261.87 224.02 1201.73 216.38 C 1141.50 208.73 1179.24 138.73 1200.44 115.44 Z M 1268.98 116.03 C 1235.51 112.38 1216.56 140.72 1208.28 168.66 C 1204.61 181.05 1207.57 188.14 1221.25 188.99 C 1252.69 190.95 1269.52 165.69 1278.11 139.53 C 1281.29 129.86 1283.04 117.57 1268.98 116.03 Z"/>
|
||||
<path fill="#212733" d=" M 178.75 138.50 L 251.22 138.50 Q 251.80 138.50 251.56 139.03 L 239.15 166.17 A 1.00 0.99 -77.3 0 1 238.25 166.75 L 165.02 166.75 Q 164.49 166.75 164.27 167.24 L 142.81 214.25 Q 142.58 214.75 142.03 214.75 L 107.23 214.75 Q 106.50 214.75 106.80 214.08 Q 121.35 182.00 136.15 149.92 C 148.48 123.20 161.98 101.63 192.25 93.75 Q 207.26 89.84 223.81 89.67 Q 248.69 89.41 273.69 89.52 A 0.33 0.33 0.0 0 1 273.99 89.98 L 261.40 117.57 A 0.71 0.70 -77.5 0 1 260.76 117.98 Q 238.06 118.04 215.53 118.01 Q 192.00 117.97 178.53 138.09 Q 178.26 138.50 178.75 138.50 Z"/>
|
||||
<path fill="#212733" d=" M 297.68 89.93 A 0.72 0.70 -77.5 0 1 298.32 89.51 Q 331.91 89.46 365.75 89.54 C 391.20 89.60 409.12 98.13 397.90 127.43 Q 387.32 155.06 358.52 164.68 Q 357.93 164.87 358.03 165.49 L 365.76 214.07 A 0.59 0.59 0.0 0 1 365.18 214.75 L 328.77 214.75 A 0.94 0.94 0.0 0 1 327.84 213.95 L 321.28 169.47 A 0.56 0.55 -4.2 0 0 320.73 169.00 L 297.78 169.00 Q 297.38 169.00 297.22 169.36 L 276.70 214.27 Q 276.48 214.75 275.96 214.75 L 241.49 214.75 A 0.53 0.53 0.0 0 1 241.01 214.00 L 297.68 89.93 Z M 319.95 120.02 L 311.09 139.31 Q 310.81 139.93 311.49 139.94 Q 327.21 140.18 342.94 139.86 Q 358.53 139.54 362.91 125.15 Q 363.54 123.07 363.57 122.84 C 363.96 119.42 354.81 119.01 352.75 119.00 Q 336.67 118.99 320.59 119.01 Q 320.18 119.01 320.03 119.39 Q 319.97 119.53 320.00 119.70 Q 320.02 119.87 319.95 120.02 Z"/>
|
||||
<path fill="#212733" d=" M 452.24 137.25 L 521.53 137.25 A 0.57 0.56 -77.8 0 1 522.04 138.05 L 509.48 165.52 Q 509.26 166.00 508.72 166.00 L 437.54 166.00 Q 437.14 166.00 436.99 166.37 C 432.13 178.79 432.96 186.25 448.54 186.24 Q 473.99 186.21 499.44 186.27 Q 500.00 186.27 499.76 186.78 L 487.23 214.20 A 0.89 0.88 -77.3 0 1 486.43 214.71 Q 462.14 214.84 438.01 214.71 C 399.97 214.50 387.18 191.81 401.76 157.22 C 418.80 116.77 444.48 90.34 490.81 89.77 Q 517.24 89.44 543.53 89.49 A 0.45 0.44 12.2 0 1 543.94 90.12 L 531.45 117.46 A 0.89 0.88 -77.3 0 1 530.65 117.97 Q 512.54 118.06 494.54 117.99 Q 480.61 117.94 475.08 119.40 Q 460.61 123.21 451.88 136.59 Q 451.46 137.25 452.24 137.25 Z"/>
|
||||
<path fill="#212733" d=" M 538.00 169.63 C 550.34 125.86 582.70 90.53 630.97 89.66 Q 652.31 89.28 684.00 89.58 Q 684.55 89.59 684.32 90.08 L 671.85 117.30 Q 671.66 117.72 671.19 117.73 Q 652.37 117.80 633.63 117.75 Q 619.99 117.72 614.51 119.20 C 594.66 124.56 584.69 146.60 577.11 163.59 C 574.05 170.46 570.41 180.21 579.55 184.44 Q 583.34 186.19 587.06 186.21 Q 613.46 186.29 639.54 186.24 A 0.53 0.52 12.2 0 1 640.02 186.98 L 627.54 214.31 Q 627.35 214.72 626.90 214.73 Q 602.22 214.81 577.50 214.72 C 549.70 214.61 529.45 199.98 538.00 169.63 Z"/>
|
||||
<path fill="#212733" d=" M 668.29 166.77 C 681.63 123.97 713.43 90.46 760.96 89.73 Q 787.18 89.33 813.51 89.54 A 0.44 0.44 0.0 0 1 813.90 90.16 L 801.48 117.24 A 0.87 0.87 0.0 0 1 800.69 117.75 Q 781.60 117.76 762.34 117.75 Q 749.65 117.74 744.29 119.25 C 723.27 125.16 712.81 148.71 705.43 167.11 C 701.14 177.80 704.15 186.14 716.82 186.19 Q 743.01 186.31 769.23 186.23 A 0.48 0.48 0.0 0 1 769.67 186.91 L 757.13 214.32 Q 756.93 214.76 756.45 214.76 Q 743.82 214.76 707.76 214.71 C 677.56 214.68 658.33 198.70 668.29 166.77 Z"/>
|
||||
<path fill="#212733" d=" M 852.81 89.50 L 889.07 89.50 A 0.37 0.37 0.0 0 1 889.41 90.02 L 832.50 214.53 A 0.37 0.37 0.0 0 1 832.16 214.75 L 795.94 214.75 A 0.37 0.37 0.0 0 1 795.60 214.23 L 852.47 89.72 A 0.37 0.37 0.0 0 1 852.81 89.50 Z"/>
|
||||
<path fill="#212733" d=" M 963.71 89.50 L 997.25 89.50 A 0.33 0.33 0.0 0 1 997.58 89.83 L 997.20 214.42 A 0.33 0.33 0.0 0 1 996.87 214.75 L 959.80 214.75 A 0.33 0.33 0.0 0 1 959.47 214.41 L 960.62 187.09 A 0.33 0.33 0.0 0 0 960.29 186.75 L 913.50 186.75 A 0.33 0.33 0.0 0 0 913.25 186.87 L 889.72 214.63 A 0.33 0.33 0.0 0 1 889.47 214.75 L 851.12 214.75 A 0.33 0.33 0.0 0 1 850.88 214.20 L 963.46 89.61 A 0.33 0.33 0.0 0 1 963.71 89.50 Z M 961.94 130.44 Q 950.71 143.69 939.23 156.88 Q 938.69 157.50 939.51 157.50 L 961.19 157.50 Q 961.88 157.50 961.91 156.81 L 963.07 130.23 A 0.47 0.47 0.0 0 0 962.39 129.79 Q 961.99 129.99 961.94 130.44 Z"/>
|
||||
<path fill="#212733" d=" M 1093.80 169.00 L 1071.20 169.00 A 1.01 1.01 0.0 0 0 1070.28 169.59 L 1049.83 214.36 Q 1049.65 214.75 1049.22 214.75 L 1014.52 214.75 A 0.45 0.45 0.0 0 1 1014.11 214.11 L 1070.70 90.24 Q 1071.03 89.53 1071.81 89.53 Q 1105.76 89.44 1140.24 89.52 C 1156.64 89.55 1178.71 94.70 1174.28 116.77 C 1169.81 139.04 1154.02 157.88 1131.83 164.51 A 0.92 0.92 0.0 0 0 1131.19 165.53 L 1138.97 214.43 A 0.28 0.28 0.0 0 1 1138.69 214.75 L 1101.56 214.75 A 0.52 0.52 0.0 0 1 1101.05 214.31 L 1094.44 169.56 A 0.65 0.65 0.0 0 0 1093.80 169.00 Z M 1093.31 119.56 L 1084.28 139.28 Q 1083.96 139.96 1084.71 139.97 Q 1094.76 140.07 1104.82 140.02 C 1121.37 139.94 1132.75 140.21 1136.76 122.66 A 1.47 1.45 -70.4 0 0 1135.99 121.02 Q 1131.90 118.99 1126.75 118.99 Q 1110.25 118.97 1094.16 119.02 A 0.94 0.93 12.3 0 0 1093.31 119.56 Z"/>
|
||||
<path fill="#212733" d=" M 1367.00 166.98 C 1351.35 167.00 1330.18 161.43 1334.95 140.26 C 1342.11 108.47 1367.59 89.66 1399.81 89.56 Q 1438.65 89.44 1477.51 89.52 A 0.49 0.49 0.0 0 1 1477.96 90.22 L 1465.09 118.32 Q 1464.89 118.75 1464.42 118.75 Q 1429.79 118.74 1395.28 118.80 Q 1379.87 118.82 1373.64 132.53 C 1372.11 135.90 1373.91 138.38 1377.44 138.41 C 1393.80 138.56 1410.76 137.63 1427.01 139.20 C 1460.30 142.42 1449.42 172.07 1437.36 189.38 C 1423.62 209.10 1402.88 214.68 1379.94 214.72 Q 1342.39 214.79 1305.22 214.74 Q 1304.38 214.73 1304.73 213.97 L 1317.48 186.02 A 0.91 0.89 12.2 0 1 1318.30 185.50 Q 1354.35 185.57 1390.73 185.29 Q 1405.11 185.17 1409.52 171.80 Q 1410.00 170.36 1409.62 168.97 A 0.99 0.98 -87.0 0 0 1409.03 168.31 Q 1405.99 167.14 1402.69 167.11 Q 1384.84 166.96 1367.00 166.98 Z"/>
|
||||
<path fill="#212733" d=" M 1494.44 109.44 C 1509.40 93.39 1528.45 89.60 1549.55 89.54 Q 1585.44 89.43 1621.33 89.53 Q 1621.83 89.53 1621.62 89.98 L 1608.68 118.24 Q 1608.46 118.74 1607.91 118.74 Q 1574.07 118.78 1540.25 118.74 C 1529.39 118.73 1519.65 123.79 1516.48 134.77 Q 1516.34 135.24 1516.57 135.67 Q 1518.10 138.52 1520.82 138.50 Q 1550.37 138.32 1565.25 138.69 Q 1571.48 138.84 1579.28 140.88 C 1605.74 147.79 1586.91 182.69 1576.81 194.47 C 1563.36 210.18 1544.20 214.66 1524.39 214.72 Q 1486.47 214.82 1448.54 214.72 A 0.38 0.37 -77.8 0 1 1448.20 214.19 L 1461.03 186.04 Q 1461.28 185.50 1461.87 185.50 Q 1494.43 185.51 1526.91 185.46 C 1540.35 185.44 1550.55 184.27 1553.34 169.97 A 1.71 1.71 0.0 0 0 1552.07 167.99 Q 1549.10 167.25 1546.18 167.21 Q 1528.34 166.97 1510.50 166.99 C 1498.51 167.00 1482.19 164.13 1478.78 150.94 C 1475.39 137.82 1485.34 119.20 1494.44 109.44 Z"/>
|
||||
<path fill="#212733" d=" M 1690.71 89.50 L 1724.17 89.50 A 0.39 0.39 0.0 0 1 1724.56 89.89 L 1724.18 214.36 A 0.39 0.39 0.0 0 1 1723.79 214.75 L 1686.83 214.75 A 0.39 0.39 0.0 0 1 1686.44 214.34 L 1687.59 187.16 A 0.39 0.39 0.0 0 0 1687.20 186.75 L 1640.52 186.75 A 0.39 0.39 0.0 0 0 1640.22 186.89 L 1616.70 214.61 A 0.39 0.39 0.0 0 1 1616.40 214.75 L 1578.23 214.75 A 0.39 0.39 0.0 0 1 1577.94 214.10 L 1690.42 89.63 A 0.39 0.39 0.0 0 1 1690.71 89.50 Z M 1688.94 130.44 Q 1677.62 143.65 1666.25 156.92 Q 1665.74 157.50 1666.51 157.50 L 1688.18 157.50 Q 1688.86 157.50 1688.89 156.82 L 1690.04 130.22 A 0.46 0.45 -12.7 0 0 1689.37 129.80 Q 1688.99 130.00 1688.94 130.44 Z"/>
|
||||
<path fill="#e41c39" d=" M 2110.65 378.00 L 2070.19 378.00 Q 2052.67 376.66 2031.50 373.51 C 1721.34 327.28 1406.93 310.07 1093.56 311.19 Q 676.72 312.68 261.93 353.87 Q 164.86 363.51 68.14 376.18 Q 60.11 377.23 52.30 377.25 Q 27.74 377.30 2.22 376.90 Q -0.44 376.85 2.17 376.36 C 204.15 337.88 409.11 314.70 614.07 299.69 Q 949.49 275.13 1285.81 277.48 C 1435.94 278.53 1586.36 283.86 1736.07 295.29 Q 1852.62 304.18 1968.28 321.03 Q 2002.91 326.08 2037.74 329.32 C 2084.15 333.63 2131.41 335.52 2177.74 329.51 C 2196.45 327.08 2236.13 318.94 2243.35 298.05 Q 2243.49 297.64 2243.76 297.98 Q 2243.94 298.22 2243.81 298.53 C 2220.62 351.89 2165.09 374.20 2110.65 378.00 Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 9.7 KiB |
9
sncf-station/public/ice.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Creator: CorelDRAW -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1.8cm" height="1cm" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 18 10" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="Ebene_x0020_1">
|
||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||
<path fill="#B4B4B4" d="M4.3579 4.9781c-0.4772,2.8024 0.6168,4.1979 3.1041,4.2241 0.8818,0.0092 1.8783,-0.2956 1.9975,-0.3663l0.229 -1.2432c-0.555,0.1967 -1.0499,0.3536 -1.7118,0.3412 -0.8359,-0.0157 -1.6762,-0.2365 -1.6981,-1.7361 -0.0315,-2.1452 0.7768,-3.9344 2.7285,-3.9707 0.6681,-0.0125 0.9846,0.1048 1.5886,0.3435l0.241 -1.3081c-0.4988,-0.2078 -0.8895,-0.3933 -2.0459,-0.4144 -2.4648,-0.0449 -4.0281,1.7523 -4.4329,4.13zm-3.6799 4.12l1.9109 -0.0011 1.4863 -8.0684 -1.9371 0 -1.4601 8.0695zm11.2907 -8.0695l-1.5412 8.0695 5.6172 -0.0006 0.2395 -1.3003 -3.7164 0 0.337 -2.0365 2.7499 0.0005 0.2488 -1.3508 -2.7181 -0.0018 0.4078 -1.9854 3.5066 -0.0002 0.2568 -1.3943 -5.3879 -0.0001z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
18
sncf-station/public/nightjet.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
style="overflow:visible"
|
||||
enable-background="new 0 0 1371.57 281.204"
|
||||
overflow="visible"
|
||||
viewBox="0 0 947.40521 151.96"
|
||||
height="151.96001"
|
||||
width="947.40515"
|
||||
id="svg3336"
|
||||
version="1.1">
|
||||
<g id="g7806" transform="translate(68.810197,566.846)">
|
||||
<path
|
||||
id="path7808"
|
||||
d="m 461.858,-518.956 -3.649,15.83 -6.74,29.12 -5.62,24.36 c -0.3,1.29 -3.7,2.76 -8.46,2.76 h -22.96 c -4.68,-0.03 -7.33,-1.48 -7.05,-2.76 l 5.62,-24.36 6.72,-29.12 1.04,-4.5 c 0.53,-2.25 -3.53,-3.6 -7.92,-3.6 h -52.7 c -0.149,0.62 -0.25,1.11 -0.3,1.35 l -13.61,60.23 c 0,0 0,0.02 0,0.03 -0.199,0.771 -1.21,1.35 -2.55,1.79 -0.13,0.04 -0.25,0.08 -0.37,0.12 -0.569,0.16 -1.149,0.3 -1.779,0.42 -0.44,0.07 -0.91,0.15 -1.41,0.2 -0.92,0.12 -1.79,0.18 -2.57,0.19 -0.05,0 -0.1,0.01 -0.16,0.01 h -0.3 -1.37 -22.52 -0.431 c -4.699,-0.03 -7.34,-1.48 -7.04,-2.76 l 18.29,-81.15 c 0,-0.02 0.021,-0.02 0.021,-0.02 l 7.52,-33.39 c 0.28,-1.19 3.88,-2.62 8.87,-2.62 h 23.73 c 5.26,0 8.189,1.47 7.92,2.62 l -6.9,30.68 c 0,0 -0.04,0.09 -0.04,0.17 20.24,0.07 69.32,0.28 69.32,0.28 3.649,0 7.06,0.29 10.14,0.83 11.548,1.98 18.639,7.31 17.258,13.29 m 90.86,-11.97 -3.319,14.66 c -0.28,1.29 -3.841,2.77 -8.851,2.77 l -9.8,-0.01 c -5.12,0.03 -9.99,1.35 -10.5,3.62 l -13.61,60.24 c -0.28,1.3 -3.84,2.78 -8.85,2.78 h -24.19 c -4.939,-0.03 -7.779,-1.49 -7.47,-2.78 l 25.84,-114.58 c 0.271,-1.18 3.89,-2.62 8.88,-2.62 h 23.721 c 5.239,0 8.189,1.48 7.939,2.62 l -6.92,30.69 h 19.18 c 5.261,0 8.23,1.41 7.95,2.61 m 325.86,0.2 -3.311,14.61 c -0.29,1.29 -3.83,2.76 -8.819,2.76 h -9.761 c -5.109,0.02 -9.96,1.33 -10.47,3.59 l -13.56,60.04 c -0.29,1.3 -3.83,2.77 -8.82,2.77 h -24.11 c -4.939,-0.02 -7.75,-1.48 -7.449,-2.77 l 25.76,-114.2 c 0.27,-1.16 3.87,-2.59 8.83,-2.59 h 23.66 c 5.22,0 8.159,1.47 7.899,2.59 l -6.899,30.6 h 19.14 c 5.21,0 8.18,1.4 7.91,2.6 m -269.179,-34.37 c 4.84,0 7.76,1.38 7.5,2.55 l -3.2,14.24 c -0.45,1.93 -5.96,2.729 -8.99,2.71 h -23.43 c -4.841,-0.02 -7.601,-1.48 -7.33,-2.71 l 3.22,-14.24 c 0.32,-1.15 3.8,-2.55 8.67,-2.55 z m -22.731,136.48 c -1.61,7.189 -16.99,13.73 -34.811,13.73 -4.8,-0.011 -7.75,-1.17 -7.449,-2.531 l 25.37,-112.37 c 0.31,-1.16 3.81,-2.56 8.68,-2.56 l 23.26,0.01 c 5.14,-0.01 8.04,1.4 7.79,2.55 z m 159.02,-80.72 c 0.62,-2.73 -3.55,-3.99 -8.05,-4.02 h -55.069 c -4.75,0 -9.65,1.29 -10.141,3.53 l -2.479,10.93 h 73.39 z m 30.7,43.17 -3.729,16.54 c -0.271,1.24 -3.82,2.71 -8.83,2.71 h -114.58 c -17.72,0 -29.97,-6.56 -28.3,-13.86 l 13.25,-58.73 c 1.63,-7.22 17.43,-13.69 35.26,-13.69 h 90.14 c 17.69,0.07 30.53,6.18 28.84,13.69 l -7.76,34.3 c -0.34,1.53 -3.899,2.99 -8.89,2.99 l -105.601,0.01 -2.149,9.57 c -0.57,2.49 3.71,3.82 8.34,3.82 h 96.39 c 5.229,0.08 7.88,1.52 7.619,2.65 m -628.42,-97.63 c 4.59,0 7.34,1.37 7.07,2.53 l -3.271,14.14 c -0.439,1.92 -5.68,2.72 -8.529,2.7 h -22.181 c -4.609,-0.02 -7.189,-1.48 -6.91,-2.7 l 3.261,-14.14 c 0.319,-1.15 3.649,-2.53 8.26,-2.53 z m -7.79,32.54 c 4.87,-0.01 7.61,1.39 7.351,2.54 l -18.261,79.05 c -0.439,1.91 -5.68,2.72 -8.54,2.7 h -22.19 c -4.58,-0.03 -7.19,-1.45 -6.87,-2.7 l 18.23,-79.05 c 0.319,-1.15 3.649,-2.55 8.26,-2.55 z m -52.46,12.08 -3.01,13.03 -6.74,29.19 -6.29,27.26 c -0.16,0.67 -1.16,1.4 -2.77,1.94 -1.471,0.49 -3.44,0.82 -5.7,0.82 h -23.03 c -2.21,-0.01 -3.97,-0.35 -5.189,-0.82 -1.37,-0.54 -2.021,-1.27 -1.87,-1.94 l 6.29,-27.26 6.74,-29.19 0.859,-3.74 c 0.53,-2.27 -3.56,-3.59 -7.96,-3.59 h -54.56 l -1.681,7.33 -6.75,29.19 -6.279,27.26 c -0.16,0.67 -1.181,1.4 -2.78,1.94 -1.47,0.49 -3.42,0.82 -5.72,0.82 h -23.011 c -2.21,-0.01 -3.97,-0.35 -5.189,-0.82 -1.351,-0.54 -2.04,-1.27 -1.86,-1.94 l 6.28,-27.26 6.74,-29.19 5.68,-24.58 c 0.33,-1.18 3.729,-2.61 8.47,-2.61 h 101.88 c 17.32,0 29.21,6.55 27.45,14.16 m 165.88,4.84 c 4.17,0 8.05,1.37 7.62,3.35 l -0.56,2.45 -0.28,1.22 -6.44,27.89 -1.01,4.37 c -0.47,2.02 -4.979,3.37 -9.22,3.37 h -43.54 c -4.23,0 -8.13,-1.35 -7.66,-3.37 l 1,-4.37 6.45,-27.89 0.84,-3.64 c 0.46,-2.01 4.99,-3.38 9.16,-3.38 z m 20.28,-18.96 h -75.44 c -16.56,0 -30.8,6.26 -32.479,13.51 l -2.87,12.47 -0.83,3.55 -0.13,0.22 -6.46,27.9 -3.49,15.15 c -1.32,5.74 5.47,10.84 16.53,12.74 2.95,0.52 6.22,0.79 9.72,0.79 h 68.01 l -2.27,9.79 c -0.47,2.05 -5.01,3.27 -9.18,3.27 h -81.5 c -4.391,0.01 -7.58,1.33 -7.99,2.44 l -0.641,2.67 c -1.68,7.331 9.671,13.581 26.24,13.581 h 75.79 c 16.36,0 30.49,-6.17 32.16,-13.34 l 0.69,-2.91 3.739,-16.29 3.83,-16.58 c 0,0 0.011,-0.01 0.011,-0.03 l 3.479,-15.06 6.43,-27.89 2.88,-12.47 c 1.681,-7.251 -9.679,-13.511 -26.229,-13.511"
|
||||
style="fill:white;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.5 KiB |
52
sncf-station/public/ouigo.svg
Normal file
@ -0,0 +1,52 @@
|
||||
<?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" width="230.88875" height="230.86626" id="svg2" version="1.1" inkscape:version="0.48.4 r9939" sodipodi:docname="Nouveau document 1">
|
||||
<defs id="defs4">
|
||||
<clipPath id="clipPath3001" clipPathUnits="userSpaceOnUse">
|
||||
<path id="path3003" d="m 120.688,3.172 353.899,0 0,365.373 -353.899,0 0,-365.373 z" inkscape:connector-curvature="0"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.35" inkscape:cx="122.4405" inkscape:cy="412.81147" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" fit-margin-top="1" fit-margin-left="1" fit-margin-right="1" fit-margin-bottom="1" inkscape:window-width="1920" inkscape:window-height="1017" inkscape:window-x="-8" inkscape:window-y="-8" inkscape:window-maximized="1"/>
|
||||
<metadata id="metadata7">
|
||||
<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>
|
||||
<g inkscape:label="Calque 1" inkscape:groupmode="layer" id="layer1" transform="translate(-252.5595,-714.3074)">
|
||||
<g id="g2997" transform="matrix(1.25,0,0,-1.25,2.953125,1058.5434)">
|
||||
<g id="g2999" clip-path="url(#clipPath3001)">
|
||||
<g id="g3005" transform="translate(292.7454,251.5881)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c -6.325,0 -10.821,5.154 -10.821,11.29 0,6.126 4.391,11.181 10.725,11.181 6.339,0 10.825,-5.164 10.825,-11.299 C 10.729,5.06 6.337,0 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3007"/>
|
||||
</g>
|
||||
<g id="g3009" transform="translate(292.7454,91.7101)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c -6.325,0 -10.821,5.147 -10.821,11.284 0,6.123 4.391,11.172 10.725,11.172 6.339,0 10.825,-5.145 10.825,-11.292 C 10.729,5.053 6.337,0 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3011"/>
|
||||
</g>
|
||||
<g id="g3013" transform="translate(383.5961,183.0498)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c 0,-50.582 -40.979,-91.554 -91.548,-91.554 -50.59,0 -91.563,40.972 -91.563,91.554 0,50.518 40.973,91.539 91.563,91.539 C -40.979,91.539 0,50.518 0,0" style="fill:#e3006a;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3015"/>
|
||||
</g>
|
||||
<g id="g3017" transform="translate(250.5055,179.1495)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 0,16.799 c 0,2.19 1.729,3.934 3.932,3.934 2.191,0 3.936,-1.744 3.936,-3.934 l 0,-16.585 c 0,-5.83 2.906,-8.839 7.705,-8.839 4.801,0 7.711,2.904 7.711,8.559 l 0,16.865 c 0,2.19 1.734,3.934 3.928,3.934 2.202,0 3.932,-1.744 3.932,-3.934 l 0,-16.551 c 0,-10.821 -6.07,-16.123 -15.676,-16.123 C 5.879,-15.875 0,-10.528 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3019"/>
|
||||
</g>
|
||||
<g id="g3021" transform="translate(286.9556,195.9439)">
|
||||
<path inkscape:connector-curvature="0" d="M 0,0 C 0,2.2 1.744,3.938 3.938,3.938 6.136,3.938 7.874,2.2 7.874,0 l 0,-28.49 c 0,-2.2 -1.738,-3.938 -3.936,-3.938 C 1.744,-32.428 0,-30.69 0,-28.49 L 0,0 z" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3023"/>
|
||||
</g>
|
||||
<g id="g3025" transform="translate(295.6633,209.2582)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c 0,-2.633 -2.138,-4.771 -4.771,-4.771 -2.632,0 -4.764,2.138 -4.764,4.771 0,2.635 2.132,4.766 4.764,4.766 C -2.138,4.766 0,2.635 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3027"/>
|
||||
</g>
|
||||
<g id="g3029" transform="translate(330.6357,184.4189)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 -9.197,0 c -1.89,0 -3.418,-1.541 -3.418,-3.429 0,-1.892 1.528,-3.367 3.418,-3.367 l 5.747,0 0,-4.89 c -1.817,-1.685 -4.401,-2.363 -8.065,-2.363 -6.322,0 -11.123,4.852 -11.123,11.38 0,6.085 4.85,11.194 10.567,11.194 3.375,0 5.667,-0.923 7.82,-2.451 0.561,-0.406 1.267,-0.809 2.395,-0.809 2.149,0 3.885,1.734 3.885,3.878 0,1.522 -0.873,2.601 -1.633,3.162 -3.223,2.251 -6.8,3.471 -12.206,3.471 -10.828,0 -19.053,-8.379 -19.053,-18.541 0,-10.563 7.97,-18.433 19.108,-18.433 5.531,0 10.201,1.687 13.591,4.326 1.743,1.335 2.106,2.391 2.106,4.696 l 0,8.251 C 3.942,-1.747 2.2,0 0,0" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3031"/>
|
||||
</g>
|
||||
<g id="g3033" transform="translate(355.9935,170.4649)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c -6.333,0 -10.819,5.154 -10.819,11.288 0,6.128 4.392,11.183 10.725,11.183 6.335,0 10.826,-5.154 10.826,-11.29 C 10.732,5.062 6.331,0 0,0 m 0,29.714 c -11.027,0 -19.047,-8.371 -19.047,-18.533 0,-10.16 7.919,-18.43 18.953,-18.43 11.02,0 19.04,8.373 19.04,18.537 0,10.16 -7.911,18.426 -18.946,18.426" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3035"/>
|
||||
</g>
|
||||
<g id="g3037" transform="translate(228.1901,170.4649)">
|
||||
<path inkscape:connector-curvature="0" d="m 0,0 c -6.34,0 -10.826,5.154 -10.826,11.288 0,6.128 4.388,11.183 10.725,11.183 6.331,0 10.822,-5.154 10.822,-11.29 C 10.721,5.062 6.325,0 0,0 m 0,29.714 c -11.033,0 -19.055,-8.371 -19.055,-18.533 0,-10.16 7.917,-18.43 18.954,-18.43 11.027,0 19.041,8.373 19.041,18.537 0,10.16 -7.915,18.426 -18.94,18.426" style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path3039"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.9 KiB |
23
sncf-station/public/renfe.svg
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="400.1" height="152.9" version="1.1" viewBox="0 0 400.1 152.9" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<style type="text/css">
|
||||
.st0{clip-path:url(#vlpa);fill:#830065;}
|
||||
</style>
|
||||
<title>Renfe</title>
|
||||
|
||||
<g transform="matrix(.1488 0 0 .1488 -8.704 -6.964)">
|
||||
|
||||
<defs>
|
||||
<rect id="vlpb" x="58.5" y="46.7" width="2689" height="1028"/>
|
||||
</defs>
|
||||
<clipPath id="vlpa">
|
||||
<use width="100%" height="100%" xlink:href="#vlpb"/>
|
||||
</clipPath>
|
||||
<path class="st0" d="m1622 355.2h-391c-20.6 115.9-54.7 314.2-71.6 411.1h166.1c12.7-72.9 47.5-272.8 62.9-360.3h124.6c52.3 0 89.9 35.3 81.2 95.8-8.3 47.9-28.4 163.3-46.1 264.5h166.1c11.8-68 34.8-199.8 45.6-261.9 14.8-84.2-29.7-149.2-137.8-149.2" clip-path="url(#vlpa)"/>
|
||||
<path class="st0" d="m773.5 717.3c-77.2-12.7-62.8-105-62.8-105 68.5 8.2 154.9 6.3 213.9 0.4 51.1-5 151.9-17.7 180.7-96.3 28.5-77.9 6.8-140.9-87.2-158.5-69.2-12.8-133.5-13.5-217.5-2.2-119.9 16.1-185.9 56.7-215.2 128-16.1 39.3-25.8 86-30.1 128.4-7.6 77.1 6.9 147.8 103.4 155.5 129.4 10.4 231.2 8.1 339-8.8l33.6-47.9c-102.3 17-218.9 12.9-257.8 6.4m-32.5-229c20.6-49 50.9-79.8 107.6-92.8 25.1-5.8 46.5-5.7 76.5 0.8 44.5 9.5 58.2 61.4 38.6 101.9-21.8 45.2-51 55.3-89.2 63.1-41.4 8.6-95.9 9.8-155.9 5.7 4.2-25.1 14.7-60.4 22.4-78.7" clip-path="url(#vlpa)"/>
|
||||
<path class="st0" d="m2404 717.3c-77.2-12.7-62.8-105-62.8-105 68.6 8.2 154.9 6.3 213.9 0.4 51.1-5 151.9-17.7 180.6-96.3 28.5-77.9 6.9-140.9-87.1-158.5-69.3-12.8-133.6-13.5-217.6-2.2-119.9 16.1-185.7 56.7-215.1 128-16.2 39.3-25.9 86-30.1 128.4-7.6 77.1 6.9 147.8 103.4 155.5 129.3 10.4 231.1 8.1 339.1-8.8l33.5-47.9c-102.3 17-218.8 12.9-257.8 6.4m-32.4-229c20.5-49 50.8-79.8 107.4-92.8 25.1-5.8 46.6-5.7 76.6 0.8 44.5 9.5 58.1 61.4 38.7 101.9-21.9 45.2-51 55.3-89.2 63.1-41.4 8.6-95.9 9.8-155.9 5.7 4.1-25.1 14.6-60.4 22.4-78.7" clip-path="url(#vlpa)"/>
|
||||
<path class="st0" d="m272.3 492.2c8.8-50.2 26.6-79.2 81.1-89.1 48.8-8.9 139.1-3 192.1 2.9l35.6-50.9c-80.3-5.8-215.9-12.4-296.3-0.7-114.6 16.6-161.3 40-174.3 113.3-7.7 43.9-42.3 242.3-52.1 298.6h166.1c11.4-65.4 39.7-227.7 47.8-274.1" clip-path="url(#vlpa)"/>
|
||||
<path class="st0" d="m2065 103.3c-94.4 66.2-126.4 147.4-143.8 247.2l-70.4 402.7c-15.8 91.6-22.8 139.4-38.4 184.4-12.5 37.7-53.6 93.1-122 94l-29.9 42.6c88.3 4.3 158.9-21.2 208.8-56.1 94.4-66.1 129.2-160.7 146.7-260.3 1.2-6.8 31.9-183.1 46.6-266.6 10.7-59.3 41.8-91.8 107.3-92.7l30.4-43.3h-114c16.2-92.4 22-132.3 35.3-170.7 13-37.7 53.7-93.1 121.9-93.9l30.4-43.3c-88.5-4.4-159 21.1-208.9 56" clip-path="url(#vlpa)"/>
|
||||
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
6
sncf-station/public/ter.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="398.9px" height="193.4px" viewBox="0 0 398.9 193.4" enable-background="new 0 0 398.9 193.4" xml:space="preserve">
|
||||
<path id="path11" fill="white" d="M143.2,144.6c0-1.2,0.1-2.4,0.4-3.6c1.5-7,6.9-14.3,13.9-18.6c22.2-13.6,40.6-9.6,43.3-8.1 c0.3,0.2,0.1,0.4-0.1,0.9c-2.5,6.4-25.6,26.7-55.2,37.5C144.1,150.4,143.2,147.3,143.2,144.6 M220,107.4c-2.8-3.1-10.2-6.5-20.2-8.1 c-9.7-1.5-29.8-2.6-51.6,8.6c-22.8,11.7-37.5,33.4-30.9,54c0.1,0-19.2,7.1-33.6,4.2c-7.8-1.6-15.1-7.3-17.4-15 c-3.6-11.8-0.6-32,19.6-50.4c26.7-24.4,66.8-33.1,83.9-36.8c7.9-1.7,8.9-2,9.1-3.1c0.1-0.5,0.4-2.3-1.2-4.2 c-2.4-2.8-9.3-5.8-28.3-3.8C129.8,55,103,62.9,95,65.4c5.5-11.5,22.5-42.1,25.5-47.9c4.9-9.4,6.7-13.4,6.7-15.6 c0-0.6-0.2-1.1-0.5-1.4c-2.8-2.6-18.8,6.1-31,20.5C83.4,35.4,76.9,47,67.2,62.2c-10.7,17-44.3,25.6-60.5,30c-4.3,1.2-5.6,1.4-6.2,2 c-0.5,0.6-0.7,1.4-0.5,2.2c1.4,4.8,9.6,9.9,18.1,10.3c6.2,0.3,13.5-0.7,25-3.9c-6.1,9.7-16.5,31.2-16.5,51.6 c0,15.9,7.3,34.8,38.4,37.8c24.5,2.3,48.2-6.4,64.9-12.8c18.8,14.6,44.4,13.8,44.5,13.8c65.7,0,96.2-52.6,101.8-62.4 c0,0.1,6,19.6,17.5,35.4c15.7,21.7,37.5,28.5,59.8,26.4c26.5-2.5,43.6-23,45.2-26.8c0.8-1.9,0-3.9-4.9-1.3 c-4.1,2.2-8.6,5.5-19.6,7.6c-49.2,9.3-63.9-41.8-74.4-63.7c-1.4-3.1-2.7-5.4-4.1-6c-3-1.2-26.2,2.9-28.7,7.8 c-25.8,48-59.4,58.7-84.8,59.1c-8.5,0.1-15.7-1.6-21.4-4.6c10-4.9,17-8.7,24.2-13.5c26.4-17.6,36-36.4,36-42.5 C220.8,108.3,220.5,107.9,220,107.4z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
2
sncf-station/public/tgv_inoui.svg
Normal file
After Width: | Height: | Size: 5.2 KiB |
17
sncf-station/public/trenitalia.svg
Normal file
After Width: | Height: | Size: 8.5 KiB |
@ -32,11 +32,32 @@ function AutocompleteStop(params) {
|
||||
filterOptions={(x) => x}
|
||||
getOptionKey={option => option.id}
|
||||
getOptionLabel={option => option.name}
|
||||
groupBy={option => option.id.startsWith("IDFM") ? "Transilien" : "TER/TGV/Intercités"}
|
||||
groupBy={option => getOptionGroup(option)}
|
||||
isOptionEqualToValue={(option, value) => option.id === value.id}
|
||||
renderInput={(params) => <TextField {...params} label="Arrêt" />}
|
||||
{...params} />
|
||||
</>
|
||||
}
|
||||
|
||||
function getOptionGroup(option) {
|
||||
switch (option.transport_type) {
|
||||
case "TGV":
|
||||
case "IC":
|
||||
case "TER":
|
||||
return "TGV/TER/Intercités"
|
||||
case "TN":
|
||||
return "Transilien"
|
||||
case "ES":
|
||||
return "Eurostar"
|
||||
case "TI":
|
||||
return "Trenitalia France"
|
||||
case "RENFE":
|
||||
return "RENFE"
|
||||
case "OBB":
|
||||
return "ÖBB"
|
||||
default:
|
||||
return option.transport_type
|
||||
}
|
||||
}
|
||||
|
||||
export default AutocompleteStop;
|
||||
|
@ -11,7 +11,8 @@ function DateTimeSelector({stop, date, time}) {
|
||||
const navigate = useNavigate()
|
||||
|
||||
function onStationSelected(event, stop) {
|
||||
navigate(`/station/${stop.id}/`)
|
||||
if (stop !== null)
|
||||
navigate(`/station/${stop.id}/`)
|
||||
}
|
||||
|
||||
return <>
|
||||
|
@ -107,7 +107,11 @@ function TrainRow({train, tableType, date, time}) {
|
||||
enabled: !!trip.route,
|
||||
})
|
||||
const route = routeQuery.data ?? {}
|
||||
const trainType = getTrainType(train, route)
|
||||
const trainType = getTrainType(train, trip, route)
|
||||
const backgroundColor = getBackgroundColor(train, trip, route)
|
||||
console.log(backgroundColor)
|
||||
const textColor = getTextColor(train, trip, route)
|
||||
const trainTypeDisplay = getTrainTypeDisplay(trainType)
|
||||
|
||||
const stopTimesQuery = useQuery({
|
||||
queryKey: ['stop_times', trip.id],
|
||||
@ -151,7 +155,6 @@ function TrainRow({train, tableType, date, time}) {
|
||||
const delay = tableType === "departures" ? realtimeData.departure_delay : realtimeData.arrival_delay
|
||||
const prettyDelay = delay && scheduleRelationship !== 3 ? getPrettyDelay(delay) : ""
|
||||
const [prettyScheduleRelationship, scheduleRelationshipColor] = getPrettyScheduleRelationship(scheduleRelationship)
|
||||
console.log(realtimeTripData)
|
||||
|
||||
let stopsFilter
|
||||
if (scheduleRelationship === 3)
|
||||
@ -174,9 +177,9 @@ function TrainRow({train, tableType, date, time}) {
|
||||
height="4em"
|
||||
borderRadius="15%"
|
||||
fontWeight="bold"
|
||||
backgroundColor={`#${getBackgroundColor(train, route)}`}
|
||||
color={`#${getTextColor(train, route)}`}>
|
||||
{trainType}
|
||||
backgroundColor={backgroundColor}
|
||||
color={textColor}>
|
||||
{trainTypeDisplay}
|
||||
</Box>
|
||||
</div>
|
||||
</TableCell>
|
||||
@ -211,46 +214,99 @@ function TrainRow({train, tableType, date, time}) {
|
||||
</>
|
||||
}
|
||||
|
||||
function getTrainType(train, route) {
|
||||
if (train.id.startsWith("IDFM"))
|
||||
return route.short_name
|
||||
else {
|
||||
let trainType = train.stop.split("StopPoint:OCE")[1].split("-")[0]
|
||||
if (trainType === "Train TER")
|
||||
trainType = "TER"
|
||||
else if (trainType === "INTERCITES")
|
||||
trainType = "INTER-CITÉS"
|
||||
else if (trainType === "INTERCITES de nuit")
|
||||
trainType = "INTER-CITÉS de nuit"
|
||||
return trainType
|
||||
function getTrainType(train, trip, route) {
|
||||
switch (route.transport_type) {
|
||||
case "TGV":
|
||||
case "TER":
|
||||
case "IC":
|
||||
let trainType = train.stop.split("StopPoint:OCE")[1].split("-")[0]
|
||||
switch (trainType) {
|
||||
case "Train TER":
|
||||
return "TER"
|
||||
case "INTERCITES":
|
||||
return "INTER-CITÉS"
|
||||
case "INTERCITES de nuit":
|
||||
return "INTER-CITÉS de nuit"
|
||||
default:
|
||||
return trainType
|
||||
}
|
||||
case "TN":
|
||||
return route.short_name
|
||||
case "ES":
|
||||
return "Eurostar"
|
||||
case "TI":
|
||||
return "Trenitalia"
|
||||
case "RENFE":
|
||||
return "RENFE"
|
||||
case "OBB":
|
||||
if (trip.short_name.startsWith("NJ"))
|
||||
return "NJ"
|
||||
return "ÖBB"
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
function getBackgroundColor(train, route) {
|
||||
if (route.color)
|
||||
return route.color
|
||||
else if (getTrainType(train, route) === "OUIGO")
|
||||
return "E60075"
|
||||
return "FFFFFF"
|
||||
function getTrainTypeDisplay(trainType) {
|
||||
switch (trainType) {
|
||||
case "TGV INOUI":
|
||||
return <img src="/tgv_inoui.svg" alt="TGV INOUI" width="80%" />
|
||||
case "OUIGO":
|
||||
return <img src="/ouigo.svg" alt="OUIGO" width="80%" />
|
||||
case "TER":
|
||||
return <img src="/ter.svg" alt="TER" width="80%" />
|
||||
case "Car TER":
|
||||
return <div><img src="/bus.svg" alt="Car" width="40%" />
|
||||
<br/>
|
||||
<img src="/ter.svg" alt="TER" width="40%" /></div>
|
||||
case "ICE":
|
||||
return <img src="/ice.svg" alt="ICE" width="80%" />
|
||||
case "Eurostar":
|
||||
return <img src="/eurostar_mini.svg" alt="Eurostar" width="80%" />
|
||||
case "Trenitalia":
|
||||
return <img src="/trenitalia.svg" alt="Frecciarossa" width="80%" />
|
||||
case "RENFE":
|
||||
return <img src="/renfe.svg" alt="RENFE" width="80%" />
|
||||
case "NJ":
|
||||
return <img src="/nightjet.svg" alt="NightJet" width="80%" />
|
||||
default:
|
||||
return trainType
|
||||
}
|
||||
}
|
||||
|
||||
function getTextColor(train, route) {
|
||||
function getBackgroundColor(train, trip, route) {
|
||||
let trainType = getTrainType(train, trip, route)
|
||||
switch (trainType) {
|
||||
case "OUIGO":
|
||||
return "#0096CA"
|
||||
case "Eurostar":
|
||||
return "#00286A"
|
||||
case "NJ":
|
||||
return "#272759"
|
||||
default:
|
||||
if (route.color)
|
||||
return `#${route.color}`
|
||||
return "#FFFFFF"
|
||||
}
|
||||
}
|
||||
|
||||
function getTextColor(train, trip, route) {
|
||||
if (route.text_color)
|
||||
return route.text_color
|
||||
return `#${route.text_color}`
|
||||
else {
|
||||
let trainType = getTrainType(train, route)
|
||||
let trainType = getTrainType(train, trip, route)
|
||||
switch (trainType) {
|
||||
case "OUIGO":
|
||||
return "FFFFFF"
|
||||
return "#FFFFFF"
|
||||
case "TGV INOUI":
|
||||
return "9B2743"
|
||||
return "#9B2743"
|
||||
case "ICE":
|
||||
return "B4B4B4"
|
||||
return "#B4B4B4"
|
||||
case "INTER-CITÉS":
|
||||
case "INTER-CITÉS de nuit":
|
||||
return "404042"
|
||||
return "#404042"
|
||||
default:
|
||||
return "000000"
|
||||
return "#000000"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ from sncfgtfs.models import Agency, Stop, Route, Trip, StopTime, Calendar, Calen
|
||||
Transfer, FeedInfo, TripUpdate, StopTimeUpdate
|
||||
|
||||
CACHE_CONTROL = cache_control(max_age=7200)
|
||||
LAST_MODIFIED = last_modified(lambda *args, **kwargs: datetime.fromisoformat(FeedInfo.objects.get().version))
|
||||
LAST_MODIFIED = last_modified(lambda *args, **kwargs: datetime.fromisoformat(
|
||||
FeedInfo.objects.get(publisher_name="SNCF_default").version))
|
||||
LOOKUP_VALUE_REGEX = r"[\w.: |-]+"
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -25,6 +27,7 @@ class AgencyViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = AgencySerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -35,6 +38,7 @@ class StopViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
filter_backends = [DjangoFilterBackend, SearchFilter]
|
||||
filterset_fields = '__all__'
|
||||
search_fields = ['name',]
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -44,6 +48,7 @@ class RouteViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = RouteSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -53,6 +58,7 @@ class TripViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = TripSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -64,6 +70,7 @@ class StopTimeViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
filterset_fields = '__all__'
|
||||
ordering_fields = ['arrival_time', 'departure_time', 'stop_sequence', ]
|
||||
ordering = ['stop_sequence', ]
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -73,6 +80,7 @@ class CalendarViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = CalendarSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -82,6 +90,7 @@ class CalendarDateViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = CalendarDateSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -90,6 +99,7 @@ class TransferViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
queryset = Transfer.objects.all()
|
||||
serializer_class = TransferSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
@method_decorator(name='list', decorator=[CACHE_CONTROL, LAST_MODIFIED])
|
||||
@ -99,6 +109,7 @@ class FeedInfoViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = FeedInfoSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
class TripUpdateViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
@ -106,6 +117,7 @@ class TripUpdateViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = TripUpdateSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
class StopTimeUpdateViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
@ -113,6 +125,7 @@ class StopTimeUpdateViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
serializer_class = StopTimeUpdateSerializer
|
||||
filter_backends = [DjangoFilterBackend]
|
||||
filterset_fields = '__all__'
|
||||
lookup_value_regex = LOOKUP_VALUE_REGEX
|
||||
|
||||
|
||||
class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
@ -140,7 +153,7 @@ class NextDeparturesViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
stop = Stop.objects.get(id=stop_id)
|
||||
stops = Stop.objects.filter(Q(id=stop_id)
|
||||
| Q(parent_station=stop_id))
|
||||
if stop.location_type == 0:
|
||||
if stop.location_type == 0 and stop.parent_station_id is not None:
|
||||
stops |= Stop.objects.filter(parent_station=stop.parent_station_id)
|
||||
stop_filter = Q(stop__in=stops.values_list('id', flat=True))
|
||||
elif stop_name:
|
||||
@ -201,7 +214,7 @@ class NextArrivalsViewSet(viewsets.ReadOnlyModelViewSet):
|
||||
stop = Stop.objects.get(id=stop_id)
|
||||
stops = Stop.objects.filter(Q(id=stop_id)
|
||||
| Q(parent_station=stop_id))
|
||||
if stop.location_type == 0:
|
||||
if stop.location_type == 0 and stop.parent_station_id is not None:
|
||||
stops |= Stop.objects.filter(parent_station=stop.parent_station_id)
|
||||
stop_filter = Q(stop__in=stops.values_list('id', flat=True))
|
||||
elif stop_name:
|
||||
|
@ -44,7 +44,7 @@ class AgencyAdmin(admin.ModelAdmin):
|
||||
@admin.register(Stop)
|
||||
class StopAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'id', 'lat', 'lon', 'location_type',)
|
||||
list_filter = ('location_type',)
|
||||
list_filter = ('location_type', 'transport_type',)
|
||||
search_fields = ('name', 'id',)
|
||||
ordering = ('name',)
|
||||
autocomplete_fields = ('parent_station',)
|
||||
@ -52,8 +52,8 @@ class StopAdmin(admin.ModelAdmin):
|
||||
|
||||
@admin.register(Route)
|
||||
class RouteAdmin(admin.ModelAdmin):
|
||||
list_display = ('long_name', 'short_name', 'id', 'type',)
|
||||
list_filter = ('type',)
|
||||
list_display = ('short_name', 'long_name', 'id', 'type',)
|
||||
list_filter = ('transport_type', 'type', 'agency',)
|
||||
search_fields = ('long_name', 'short_name', 'id',)
|
||||
ordering = ('long_name',)
|
||||
autocomplete_fields = ('agency',)
|
||||
|
@ -17,6 +17,10 @@ class Command(BaseCommand):
|
||||
"IC": "https://eu.ftp.opendatasoft.com/sncf/gtfs/export-intercites-gtfs-last.zip",
|
||||
"TER": "https://eu.ftp.opendatasoft.com/sncf/gtfs/export-ter-gtfs-last.zip",
|
||||
"TN": "https://eu.ftp.opendatasoft.com/sncf/gtfs/transilien-gtfs.zip",
|
||||
# "ES": "https://www.data.gouv.fr/fr/datasets/r/9089b550-696e-4ae0-87b5-40ea55a14292",
|
||||
# "TI": "https://www.data.gouv.fr/fr/datasets/r/4d1dd21a-b061-47ac-9514-57ffcc09b4a5",
|
||||
# "RENFE": "https://ssl.renfe.com/gtransit/Fichero_AV_LD/google_transit.zip",
|
||||
# "OBB": "https://static.oebb.at/open-data/soll-fahrplan-gtfs/GTFS_OP_2024_obb.zip",
|
||||
}
|
||||
|
||||
def add_arguments(self, parser):
|
||||
@ -35,10 +39,13 @@ class Command(BaseCommand):
|
||||
if not FeedInfo.objects.exists():
|
||||
last_update_date = "1970-01-01"
|
||||
else:
|
||||
last_update_date = FeedInfo.objects.get().version
|
||||
last_update_date = FeedInfo.objects.get(publisher_name='SNCF_default').version
|
||||
|
||||
for url in self.GTFS_FEEDS.values():
|
||||
last_modified = requests.head(url).headers["Last-Modified"]
|
||||
resp = requests.head(url)
|
||||
if "Last-Modified" not in resp.headers:
|
||||
continue
|
||||
last_modified = resp.headers["Last-Modified"]
|
||||
last_modified = datetime.strptime(last_modified, "%a, %d %b %Y %H:%M:%S %Z")
|
||||
if last_modified.date().isoformat() > last_update_date:
|
||||
break
|
||||
@ -54,15 +61,22 @@ class Command(BaseCommand):
|
||||
for transport_type, feed_url in self.GTFS_FEEDS.items():
|
||||
self.stdout.write(f"Downloading {transport_type} GTFS feed...")
|
||||
with ZipFile(BytesIO(requests.get(feed_url).content)) as zipfile:
|
||||
def read_file(filename):
|
||||
lines = zipfile.read(filename).decode().replace('\ufeff', '').splitlines()
|
||||
return [line.strip() for line in lines]
|
||||
|
||||
agencies = []
|
||||
for agency_dict in csv.DictReader(zipfile.read("agency.txt").decode().splitlines()):
|
||||
for agency_dict in csv.DictReader(read_file("agency.txt")):
|
||||
agency_dict: dict
|
||||
if transport_type == "ES" \
|
||||
and agency_dict['agency_id'] != 'ES' and agency_dict['agency_id'] != 'ER':
|
||||
continue
|
||||
agency = Agency(
|
||||
id=agency_dict['agency_id'],
|
||||
name=agency_dict['agency_name'],
|
||||
url=agency_dict['agency_url'],
|
||||
timezone=agency_dict['agency_timezone'],
|
||||
lang=agency_dict['agency_lang'],
|
||||
lang=agency_dict.get('agency_lang', "fr"),
|
||||
phone=agency_dict.get('agency_phone', ""),
|
||||
email=agency_dict.get('agency_email', ""),
|
||||
)
|
||||
@ -75,23 +89,28 @@ class Command(BaseCommand):
|
||||
agencies.clear()
|
||||
|
||||
stops = []
|
||||
for stop_dict in csv.DictReader(zipfile.read("stops.txt").decode().splitlines()):
|
||||
for stop_dict in csv.DictReader(read_file("stops.txt")):
|
||||
stop_dict: dict
|
||||
stop_id = stop_dict['stop_id']
|
||||
if transport_type in ["ES", "TI", "RENFE"]:
|
||||
stop_id = f"{transport_type}-{stop_id}"
|
||||
|
||||
stop = Stop(
|
||||
id=stop_dict["stop_id"],
|
||||
id=stop_id,
|
||||
name=stop_dict['stop_name'],
|
||||
desc=stop_dict['stop_desc'],
|
||||
desc=stop_dict.get('stop_desc', ""),
|
||||
lat=stop_dict['stop_lat'],
|
||||
lon=stop_dict['stop_lon'],
|
||||
zone_id=stop_dict['zone_id'],
|
||||
url=stop_dict['stop_url'],
|
||||
location_type=stop_dict['location_type'],
|
||||
parent_station_id=stop_dict['parent_station'] or None
|
||||
zone_id=stop_dict.get('zone_id', ""),
|
||||
url=stop_dict.get('stop_url', ""),
|
||||
location_type=stop_dict.get('location_type', 1) or 1,
|
||||
parent_station_id=stop_dict.get('parent_station', None) or None
|
||||
if last_update_date != "1970-01-01" or transport_type != "TN" else None,
|
||||
timezone=stop_dict.get('stop_timezone', ""),
|
||||
wheelchair_boarding=stop_dict.get('wheelchair_boarding', 0),
|
||||
level_id=stop_dict.get('level_id', ""),
|
||||
platform_code=stop_dict.get('platform_code', ""),
|
||||
transport_type=transport_type,
|
||||
)
|
||||
stops.append(stop)
|
||||
|
||||
@ -100,7 +119,8 @@ class Command(BaseCommand):
|
||||
update_conflicts=True,
|
||||
update_fields=['name', 'desc', 'lat', 'lon', 'zone_id', 'url',
|
||||
'location_type', 'parent_station_id', 'timezone',
|
||||
'wheelchair_boarding', 'level_id', 'platform_code'],
|
||||
'wheelchair_boarding', 'level_id', 'platform_code',
|
||||
'transport_type'],
|
||||
unique_fields=['id'])
|
||||
stops.clear()
|
||||
if stops and not dry_run:
|
||||
@ -108,23 +128,27 @@ class Command(BaseCommand):
|
||||
update_conflicts=True,
|
||||
update_fields=['name', 'desc', 'lat', 'lon', 'zone_id', 'url',
|
||||
'location_type', 'parent_station_id', 'timezone',
|
||||
'wheelchair_boarding', 'level_id', 'platform_code'],
|
||||
'wheelchair_boarding', 'level_id', 'platform_code',
|
||||
'transport_type'],
|
||||
unique_fields=['id'])
|
||||
stops.clear()
|
||||
|
||||
routes = []
|
||||
for route_dict in csv.DictReader(zipfile.read("routes.txt").decode().splitlines()):
|
||||
for route_dict in csv.DictReader(read_file("routes.txt")):
|
||||
route_dict: dict
|
||||
route_id = route_dict['route_id']
|
||||
if transport_type == "TI":
|
||||
route_id = f"{transport_type}-{route_id}"
|
||||
route = Route(
|
||||
id=route_dict['route_id'],
|
||||
id=route_id,
|
||||
agency_id=route_dict['agency_id'],
|
||||
short_name=route_dict['route_short_name'],
|
||||
long_name=route_dict['route_long_name'],
|
||||
desc=route_dict['route_desc'],
|
||||
desc=route_dict.get('route_desc', ""),
|
||||
type=route_dict['route_type'],
|
||||
url=route_dict['route_url'],
|
||||
color=route_dict['route_color'],
|
||||
text_color=route_dict['route_text_color'],
|
||||
url=route_dict.get('route_url', ""),
|
||||
color=route_dict.get('route_color', ""),
|
||||
text_color=route_dict.get('route_text_color', ""),
|
||||
transport_type=transport_type,
|
||||
)
|
||||
routes.append(route)
|
||||
@ -141,14 +165,15 @@ class Command(BaseCommand):
|
||||
Route.objects.bulk_create(routes,
|
||||
update_conflicts=True,
|
||||
update_fields=['agency_id', 'short_name', 'long_name', 'desc',
|
||||
'type', 'url', 'color', 'text_color'],
|
||||
'type', 'url', 'color', 'text_color',
|
||||
'transport_type'],
|
||||
unique_fields=['id'])
|
||||
routes.clear()
|
||||
|
||||
calendar_ids = []
|
||||
if "calendar.txt" in zipfile.namelist():
|
||||
calendars = []
|
||||
for calendar_dict in csv.DictReader(zipfile.read("calendar.txt").decode().splitlines()):
|
||||
for calendar_dict in csv.DictReader(read_file("calendar.txt")):
|
||||
calendar_dict: dict
|
||||
calendar = Calendar(
|
||||
id=f"{transport_type}-{calendar_dict['service_id']}",
|
||||
@ -184,7 +209,7 @@ class Command(BaseCommand):
|
||||
|
||||
calendars = []
|
||||
calendar_dates = []
|
||||
for calendar_date_dict in csv.DictReader(zipfile.read("calendar_dates.txt").decode().splitlines()):
|
||||
for calendar_date_dict in csv.DictReader(read_file("calendar_dates.txt")):
|
||||
calendar_date_dict: dict
|
||||
calendar_date = CalendarDate(
|
||||
id=f"{transport_type}-{calendar_date_dict['service_id']}-{calendar_date_dict['date']}",
|
||||
@ -235,23 +260,31 @@ class Command(BaseCommand):
|
||||
calendar_dates.clear()
|
||||
|
||||
trips = []
|
||||
for trip_dict in csv.DictReader(zipfile.read("trips.txt").decode().splitlines()):
|
||||
for trip_dict in csv.DictReader(read_file("trips.txt")):
|
||||
trip_dict: dict
|
||||
trip_id = trip_dict['trip_id']
|
||||
if transport_type != "TN":
|
||||
route_id = trip_dict['route_id']
|
||||
if transport_type in ["TGV", "IC", "TER"]:
|
||||
trip_id, last_update = trip_id.split(':', 1)
|
||||
last_update = datetime.fromisoformat(last_update)
|
||||
elif transport_type in ["ES", "RENFE"]:
|
||||
trip_id = f"{transport_type}-{trip_id}"
|
||||
last_update = None
|
||||
elif transport_type == "TI":
|
||||
trip_id = f"{transport_type}-{trip_id}"
|
||||
route_id = f"{transport_type}-{route_id}"
|
||||
last_update = None
|
||||
else:
|
||||
last_update = None
|
||||
trip = Trip(
|
||||
id=trip_id,
|
||||
route_id=trip_dict['route_id'],
|
||||
route_id=route_id,
|
||||
service_id=f"{transport_type}-{trip_dict['service_id']}",
|
||||
headsign=trip_dict['trip_headsign'],
|
||||
headsign=trip_dict.get('trip_headsign', ""),
|
||||
short_name=trip_dict.get('trip_short_name', ""),
|
||||
direction_id=trip_dict['direction_id'] or None,
|
||||
block_id=trip_dict['block_id'],
|
||||
shape_id=trip_dict['shape_id'],
|
||||
direction_id=trip_dict.get('direction_id', None) or None,
|
||||
block_id=trip_dict.get('block_id', ""),
|
||||
shape_id=trip_dict.get('shape_id', ""),
|
||||
wheelchair_accessible=trip_dict.get('wheelchair_accessible', None),
|
||||
bikes_allowed=trip_dict.get('bikes_allowed', None),
|
||||
last_update=last_update,
|
||||
@ -278,26 +311,49 @@ class Command(BaseCommand):
|
||||
all_trips.extend(trips)
|
||||
|
||||
stop_times = []
|
||||
for stop_time_dict in csv.DictReader(zipfile.read("stop_times.txt").decode().splitlines()):
|
||||
for stop_time_dict in csv.DictReader(read_file("stop_times.txt")):
|
||||
stop_time_dict: dict
|
||||
|
||||
stop_id = stop_time_dict['stop_id']
|
||||
if transport_type in ["ES", "TI", "RENFE"]:
|
||||
stop_id = f"{transport_type}-{stop_id}"
|
||||
|
||||
trip_id = stop_time_dict['trip_id']
|
||||
if transport_type != "TN":
|
||||
if transport_type in ["TGV", "IC", "TER"]:
|
||||
trip_id = trip_id.split(':', 1)[0]
|
||||
elif transport_type in ["ES", "TI", "RENFE"]:
|
||||
trip_id = f"{transport_type}-{trip_id}"
|
||||
|
||||
arr_time = stop_time_dict['arrival_time']
|
||||
arr_time = int(arr_time[:2]) * 3600 + int(arr_time[3:5]) * 60 + int(arr_time[6:])
|
||||
arr_h, arr_m, arr_s = map(int, arr_time.split(':'))
|
||||
arr_time = arr_h * 3600 + arr_m * 60 + arr_s
|
||||
dep_time = stop_time_dict['departure_time']
|
||||
dep_time = int(dep_time[:2]) * 3600 + int(dep_time[3:5]) * 60 + int(dep_time[6:])
|
||||
dep_h, dep_m, dep_s = map(int, dep_time.split(':'))
|
||||
dep_time = dep_h * 3600 + dep_m * 60 + dep_s
|
||||
|
||||
pickup_type = stop_time_dict.get('pickup_type', 0)
|
||||
drop_off_type = stop_time_dict.get('drop_off_type', 0)
|
||||
if transport_type in ["ES", "RENFE", "OBB"]:
|
||||
if stop_time_dict['stop_sequence'] == "1":
|
||||
drop_off_type = 1
|
||||
elif arr_time == dep_time:
|
||||
pickup_type = 1
|
||||
elif transport_type == "TI":
|
||||
if stop_time_dict['stop_sequence'] == "0":
|
||||
drop_off_type = 1
|
||||
elif arr_time == dep_time:
|
||||
pickup_type = 1
|
||||
|
||||
st = StopTime(
|
||||
id=f"{stop_time_dict['trip_id']}-{stop_time_dict['stop_id']}",
|
||||
id=f"{trip_id}-{stop_id}",
|
||||
trip_id=trip_id,
|
||||
arrival_time=timedelta(seconds=arr_time),
|
||||
departure_time=timedelta(seconds=dep_time),
|
||||
stop_id=stop_time_dict['stop_id'],
|
||||
stop_id=stop_id,
|
||||
stop_sequence=stop_time_dict['stop_sequence'],
|
||||
stop_headsign=stop_time_dict['stop_headsign'],
|
||||
pickup_type=stop_time_dict['pickup_type'],
|
||||
drop_off_type=stop_time_dict['drop_off_type'],
|
||||
stop_headsign=stop_time_dict.get('stop_headsign', ""),
|
||||
pickup_type=pickup_type,
|
||||
drop_off_type=drop_off_type,
|
||||
timepoint=stop_time_dict.get('timepoint', None),
|
||||
)
|
||||
stop_times.append(st)
|
||||
@ -319,42 +375,49 @@ class Command(BaseCommand):
|
||||
unique_fields=['id'])
|
||||
stop_times.clear()
|
||||
|
||||
transfers = []
|
||||
for transfer_dict in csv.DictReader(zipfile.read("transfers.txt").decode().splitlines()):
|
||||
transfer_dict: dict
|
||||
transfer = Transfer(
|
||||
id=f"{transfer_dict['from_stop_id']}-{transfer_dict['to_stop_id']}",
|
||||
from_stop_id=transfer_dict['from_stop_id'],
|
||||
to_stop_id=transfer_dict['to_stop_id'],
|
||||
transfer_type=transfer_dict['transfer_type'],
|
||||
min_transfer_time=transfer_dict['min_transfer_time'],
|
||||
)
|
||||
transfers.append(transfer)
|
||||
if "transfers.txt" in zipfile.namelist():
|
||||
transfers = []
|
||||
for transfer_dict in csv.DictReader(read_file("transfers.txt")):
|
||||
transfer_dict: dict
|
||||
from_stop_id = transfer_dict['from_stop_id']
|
||||
to_stop_id = transfer_dict['to_stop_id']
|
||||
if transport_type in ["ES", "RENFE", "OBB"]:
|
||||
from_stop_id = f"{transport_type}-{from_stop_id}"
|
||||
to_stop_id = f"{transport_type}-{to_stop_id}"
|
||||
|
||||
if len(transfers) >= bulk_size and not dry_run:
|
||||
transfer = Transfer(
|
||||
id=f"{from_stop_id}-{to_stop_id}",
|
||||
from_stop_id=transfer_dict['from_stop_id'],
|
||||
to_stop_id=transfer_dict['to_stop_id'],
|
||||
transfer_type=transfer_dict['transfer_type'],
|
||||
min_transfer_time=transfer_dict['min_transfer_time'],
|
||||
)
|
||||
transfers.append(transfer)
|
||||
|
||||
if len(transfers) >= bulk_size and not dry_run:
|
||||
Transfer.objects.bulk_create(transfers,
|
||||
update_conflicts=True,
|
||||
update_fields=['transfer_type', 'min_transfer_time'],
|
||||
unique_fields=['id'])
|
||||
transfers.clear()
|
||||
|
||||
if transfers and not dry_run:
|
||||
Transfer.objects.bulk_create(transfers,
|
||||
update_conflicts=True,
|
||||
update_fields=['transfer_type', 'min_transfer_time'],
|
||||
unique_fields=['id'])
|
||||
transfers.clear()
|
||||
|
||||
if transfers and not dry_run:
|
||||
Transfer.objects.bulk_create(transfers,
|
||||
update_conflicts=True,
|
||||
update_fields=['transfer_type', 'min_transfer_time'],
|
||||
unique_fields=['id'])
|
||||
transfers.clear()
|
||||
|
||||
if "feed_info.txt" in zipfile.namelist() and not dry_run:
|
||||
for feed_info_dict in csv.DictReader(zipfile.read("feed_info.txt").decode().splitlines()):
|
||||
for feed_info_dict in csv.DictReader(read_file("feed_info.txt")):
|
||||
feed_info_dict: dict
|
||||
FeedInfo.objects.update_or_create(
|
||||
publisher_name=feed_info_dict['feed_publisher_name'],
|
||||
defaults=dict(
|
||||
publisher_url=feed_info_dict['feed_publisher_url'],
|
||||
lang=feed_info_dict['feed_lang'],
|
||||
start_date=feed_info_dict['feed_start_date'],
|
||||
end_date=feed_info_dict['feed_end_date'],
|
||||
version=feed_info_dict['feed_version'],
|
||||
start_date=feed_info_dict.get('feed_start_date', datetime.now().date()),
|
||||
end_date=feed_info_dict.get('feed_end_date', datetime.now().date()),
|
||||
version=feed_info_dict.get('feed_version', 1),
|
||||
)
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.0.1 on 2024-02-09 21:55
|
||||
# Generated by Django 5.0.1 on 2024-02-10 16:30
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
@ -22,12 +22,7 @@ class Migration(migrations.Migration):
|
||||
verbose_name="Agency ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"name",
|
||||
models.CharField(
|
||||
max_length=255, unique=True, verbose_name="Agency name"
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=255, verbose_name="Agency name")),
|
||||
("url", models.URLField(verbose_name="Agency URL")),
|
||||
(
|
||||
"timezone",
|
||||
@ -87,6 +82,10 @@ class Migration(migrations.Migration):
|
||||
("TER", "TER"),
|
||||
("IC", "Intercités"),
|
||||
("TN", "Transilien"),
|
||||
("ES", "Eurostar"),
|
||||
("TI", "Trenitalia"),
|
||||
("RENFE", "Renfe"),
|
||||
("OBB", "ÖBB"),
|
||||
],
|
||||
max_length=255,
|
||||
verbose_name="Transport type",
|
||||
@ -234,6 +233,10 @@ class Migration(migrations.Migration):
|
||||
("TER", "TER"),
|
||||
("IC", "Intercités"),
|
||||
("TN", "Transilien"),
|
||||
("ES", "Eurostar"),
|
||||
("TI", "Trenitalia"),
|
||||
("RENFE", "Renfe"),
|
||||
("OBB", "ÖBB"),
|
||||
],
|
||||
max_length=255,
|
||||
verbose_name="Transport type",
|
||||
@ -330,6 +333,23 @@ class Migration(migrations.Migration):
|
||||
blank=True, max_length=255, verbose_name="Platform code"
|
||||
),
|
||||
),
|
||||
(
|
||||
"transport_type",
|
||||
models.CharField(
|
||||
choices=[
|
||||
("TGV", "TGV"),
|
||||
("TER", "TER"),
|
||||
("IC", "Intercités"),
|
||||
("TN", "Transilien"),
|
||||
("ES", "Eurostar"),
|
||||
("TI", "Trenitalia"),
|
||||
("RENFE", "Renfe"),
|
||||
("OBB", "ÖBB"),
|
||||
],
|
||||
max_length=255,
|
||||
verbose_name="Transport type",
|
||||
),
|
||||
),
|
||||
(
|
||||
"parent_station",
|
||||
models.ForeignKey(
|
||||
|
@ -7,6 +7,10 @@ class TransportType(models.TextChoices):
|
||||
TER = "TER", _("TER")
|
||||
INTERCITES = "IC", _("Intercités")
|
||||
TRANSILIEN = "TN", _("Transilien")
|
||||
EUROSTAR = "ES", _("Eurostar")
|
||||
TRENITALIA = "TI", _("Trenitalia")
|
||||
RENFE = "RENFE", _("Renfe")
|
||||
OBB = "OBB", _("ÖBB")
|
||||
|
||||
|
||||
class LocationType(models.IntegerChoices):
|
||||
@ -84,7 +88,6 @@ class Agency(models.Model):
|
||||
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
unique=True,
|
||||
verbose_name=_("Agency name"),
|
||||
)
|
||||
|
||||
@ -206,6 +209,12 @@ class Stop(models.Model):
|
||||
blank=True,
|
||||
)
|
||||
|
||||
transport_type = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Transport type"),
|
||||
choices=TransportType,
|
||||
)
|
||||
|
||||
@property
|
||||
def stop_type(self):
|
||||
train_type = self.id.split('StopPoint:OCE')[1].split('-')[0]
|
||||
|