@digitransit/

Vehicle_Positions_Map_Demo

HTML, CSS, JS

Display vehicle data from HFP API (MQTT) on a map

fork
loading
Files
  • index.html
  • index.css
  • index.js

This Plugin Crashed!

Error: Error: must not create an existing file {"type":"CREATE_FILE","wid":"0.28657730399327463","path":"index.html","file":{"path":"index.html","content":{"asEncoding":{"base64":"PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgY2hhcnNldD0idXRmLTgiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCI+CiAgICA8dGl0bGU+TVFUVCBtYXA8L3RpdGxlPgogICAgPGxpbmsgaHJlZj0iaW5kZXguY3NzIiByZWw9InN0eWxlc2hlZXQiIHR5cGU9InRleHQvY3NzIiAvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL3VucGtnLmNvbS9sZWFmbGV0QDEuMy4xL2Rpc3QvbGVhZmxldC5jc3MiIC8+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly91bnBrZy5jb20vbGVhZmxldEAxLjMuMS9kaXN0L2xlYWZsZXQuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2xlYWZsZXQtcmVhbHRpbWUvMi4xLjEvbGVhZmxldC1yZWFsdGltZS5taW4uanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdCBzcmM9Imh0dHBzOi8vdW5wa2cuY29tL21xdHRAMi4xOC44L2Rpc3QvbXF0dC5taW4uanMiPjwvc2NyaXB0PgogIDwvaGVhZD4KICA8Ym9keT4KICAgIDxwIGlkPSJkb2N1bWVudGF0aW9uX25vdGUiPlJlYWQgdGhlIDxhIGhyZWY9Imh0dHBzOi8vZGlnaXRyYW5zaXQuZmkvZW4vZGV2ZWxvcGVycy9hcGlzLzQtcmVhbHRpbWUtYXBpL3ZlaGljbGUtcG9zaXRpb25zLyI+SEZQIEFQSSBkb2N1bWVudGF0aW9uPC9hPiB0byB1bmRlcnN0YW5kIGhvdyB0aGVzZSB0b3BpYyBmaWx0ZXJzIGFyZSB1c2VkPC9wPgoKICAgIDx0YWJsZT4KICAgICAgPHRyIGNsYXNzPSJ0b3BpY192YWx1ZSI+CiAgICAgICAgPHRkPlRlbXBvcmFsIHR5cGU6IDwvdGQ+CiAgICAgICAgPHRkPjxzZWxlY3QgY2xhc3M9InZhbHVlIiBpZD0idGVtcG9yYWxfdHlwZSI+CiAgICAgICAgICAgICAgPG9wdGlvbj4rPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj5vbmdvaW5nPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj51cGNvbWluZzwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L3RkPgogICAgICA8L3RyPgogICAgICAgICAgCiAgICAgIDx0ciBjbGFzcz0idG9waWNfdmFsdWUiPgogICAgICAgIDx0ZD5UcmFuc3BvcnQgbW9kZTogPC90ZD4KICAgICAgICA8dGQ+PHNlbGVjdCBjbGFzcz0idmFsdWUiIGlkPSJ0cmFuc3BvcnRfbW9kZSI+CiAgICAgICAgICAgIDxvcHRpb24+Kzwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uPmJ1czwvb3B0aW9uPgogICAgICAgICAgICA8b3B0aW9uPnRyYW08L29wdGlvbj4KICAgICAgICAgICAgPG9wdGlvbj50cmFpbjwvb3B0aW9uPgogICAgICAgICAgPC9zZWxlY3Q+CiAgICAgICAgPC90ZD4KICAgICAgPC90cj4KCiAgICAgIDx0ciBjbGFzcz0idG9waWNfdmFsdWUiPgogICAgICAgIDx0ZD5PcGVyYXRvciBpZDogPC90ZD4KICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPSJ2YWx1ZSIgaWQ9Im9wZXJhdG9yX2lkIiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iKyI+PC9pbnB1dD48L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idmFsaWRhdGlvbl9ub3RlIj5PcGVyYXRvciBpZCBzaG91bGQgYmUgNCBkaWdpdHMgbG9uZzx0ZD4KICAgICAgPC90cj4KCiAgICAgIDx0ciBjbGFzcz0idG9waWNfdmFsdWUiPgogICAgICAgIDx0ZD5WZWhpY2xlIG51bWJlcjogPC90ZD4KICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPSJ2YWx1ZSIgaWQ9InZlaGljbGVfbnVtYmVyIiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iKyI+PC9pbnB1dD48L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idmFsaWRhdGlvbl9ub3RlIj5WZWhpY2xlIG51bWJlciBzaG91bGQgYmUgNSBkaWdpdHMgbG9uZzx0ZD4KICAgICAgPC90cj4KCiAgICAgIDx0ciBjbGFzcz0idG9waWNfdmFsdWUiPgogICAgICAgIDx0ZD5Sb3V0ZSBpZDogPC90ZD4KICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPSJ2YWx1ZSIgaWQ9InJvdXRlX2lkIiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iKyI+PC9pbnB1dD48L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idmFsaWRhdGlvbl9ub3RlIj5Sb3V0ZSBpZCBzaG91bGQgY29udGFpbiA0IGRpZ2l0cyBhbmQgdXAgdG8gMiBjaGFyYWN0ZXJzPHRkPgogICAgICA8L3RyPgoKICAgICAgPHRyIGNsYXNzPSJ0b3BpY192YWx1ZSI+CiAgICAgICAgPHRkPkRpcmVjdGlvbiBpZDogPC90ZD4KICAgICAgICA8dGQ+PHNlbGVjdCBjbGFzcz0idmFsdWUiIGlkPSJkaXJlY3Rpb25faWQiPgogICAgICAgICAgICAgIDxvcHRpb24+Kzwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24+MTwvb3B0aW9uPgogICAgICAgICAgICAgIDxvcHRpb24+Mjwvb3B0aW9uPgogICAgICAgICAgICA8L3NlbGVjdD4KICAgICAgICA8L3RkPgogICAgICA8L3RyPgoKICAgICAgPHRyIGNsYXNzPSJ0b3BpY192YWx1ZSI+CiAgICAgICAgPHRkPkhlYWRzaWduOiA8L3RkPgogICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9InZhbHVlIiBpZD0iaGVhZHNpZ24iIHR5cGU9InRleHQiIHZhbHVlPSIrIj48L2lucHV0PjwvdGQ+CiAgICAgIDwvdHI+CgogICAgICA8dHIgY2xhc3M9InRvcGljX3ZhbHVlIj4KICAgICAgICA8dGQ+U3RhcnQgdGltZTogPC90ZD4KICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPSJ2YWx1ZSIgaWQ9InN0YXJ0X3RpbWUiIHR5cGU9InRleHQiIHZhbHVlPSIrIj48L2lucHV0PjwvdGQ+CiAgICAgICAgPHRkIGNsYXNzPSJ2YWxpZGF0aW9uX25vdGUiPlRpbWUgc2hvdWxkIGJlIGluIGZvcm1hdCA8Y29kZT5oaDpNTTwvY29kZT48dGQ+CiAgICAgIDwvdHI+CgogICAgICA8dHIgY2xhc3M9InRvcGljX3ZhbHVlIj4KICAgICAgICA8dGQ+TmV4dCBzdG9wOiA8L3RkPgogICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9InZhbHVlIiBpZD0ibmV4dF9zdG9wIiB0eXBlPSJ0ZXh0IiB2YWx1ZT0iKyI+PC9pbnB1dD48L3RkPgogICAgICAgIDx0ZCBjbGFzcz0idmFsaWRhdGlvbl9ub3RlIj5TdG9wIGlkIHNob3VsZCBiZSA3IGRpZ2l0cyBsb25nPHRkPgogICAgICA8L3RyPgoKICAgICAgPHRyIGNsYXNzPSJ0b3BpY192YWx1ZSI+CiAgICAgICAgPHRkPkdlb2hhc2ggbGV2ZWw6IDwvdGQ+CiAgICAgICAgPHRkPjxzZWxlY3QgY2xhc3M9InZhbHVlIiBpZD0iZ2VvaGFzaF9sZXZlbCI+CiAgICAgICAgICAgICAgPG9wdGlvbj4wPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj4xPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj4yPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj4zPC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj40PC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj41PC9vcHRpb24+CiAgICAgICAgICAgICAgPG9wdGlvbj4rPC9vcHRpb24+CiAgICAgICAgICAgIDwvc2VsZWN0PjwvdGQ+CiAgICAgICAgICA8dGQgaWQ9Imdlb2hhc2hfbm90ZSI+PGI+Tm90ZTo8L2I+IEdlb2hhc2ggbGV2ZWwgMCBzaG93cyBvbmx5IHRoZSBtb3N0IHNpZ25pZmljYW50IHVwZGF0ZXMgb24gdGhlIG1hcDwvdGQ+CiAgICAgIDwvdHI+CiAgICA8L3RhYmxlPgoKICAgIDxhIGlkPSJzaG93X3RvcGljcyIgaHJlZj0iamF2YXNjcmlwdDo7IiBvbmNsaWNrPSJzaG93VG9waWNzKCkiPlNob3cgdG9waWNzPC9hPgogICAgPHByZSBpZD0idG9waWNzIiBzdHlsZT0iZGlzcGxheTpub25lIj48L3ByZT4KCiAgICA8ZGl2IGlkPSJtYXBfY29udGFpbmVyIj4KICAgICAgPGRpdj48YnV0dG9uIGNsYXNzPSJnZW9maWx0ZXIiIGlkPSJnZW9oYXNoX29uIj5Vc2UgbWFwIGJvdW5kcyBmb3IgZ2VvaGFzaCBmaWx0ZXI8L2J1dHRvbj48YnV0dG9uIGNsYXNzPSJnZW9maWx0ZXIiIGlkPSJnZW9oYXNoX29mZiI+UmVtb3ZlIGdlb2hhc2ggZmlsdGVyPC9idXR0b24+PC9kaXY+CiAgICAgIDxici8+CiAgICAgIDxkaXYgaWQ9Im1hcCI+PC9kaXY+CiAgICA8L2Rpdj4KICAgIDxzY3JpcHQgc3JjPSJpbmRleC5qcyI+PC9zY3JpcHQ+CiAgPC9ib2R5Pgo8L2h0bWw+"},"asBuffer":null},"loaded":true}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>MQTT map</title>
    <link href="index.css" rel="stylesheet" type="text/css" />
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-realtime/2.1.1/leaflet-realtime.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/mqtt.min.js"></script>
  </head>
  <body>
    <p id="documentation_note">Read the <a href="https://digitransit.fi/en/developers/apis/4-realtime-api/vehicle-positions/">HFP API documentation</a> to understand how these topic filters are used</p>

    <table>
      <tr class="topic_value">
        <td>Temporal type: </td>
        <td><select class="value" id="temporal_type">
              <option>+</option>
              <option>ongoing</option>
              <option>upcoming</option>
            </select>
        </td>
      </tr>
          
      <tr class="topic_value">
        <td>Transport mode: </td>
        <td><select class="value" id="transport_mode">
            <option>+</option>
            <option>bus</option>
            <option>tram</option>
            <option>train</option>
          </select>
        </td>
      </tr>

      <tr class="topic_value">
        <td>Operator id: </td>
        <td><input class="value" id="operator_id" type="text" value="+"></input></td>
        <td class="validation_note">Operator id should be 4 digits long<td>
      </tr>

      <tr class="topic_value">
        <td>Vehicle number: </td>
        <td><input class="value" id="vehicle_number" type="text" value="+"></input></td>
        <td class="validation_note">Vehicle number should be 5 digits long<td>
      </tr>

      <tr class="topic_value">
        <td>Route id: </td>
        <td><input class="value" id="route_id" type="text" value="+"></input></td>
        <td class="validation_note">Route id should contain 4 digits and up to 2 characters<td>
      </tr>

      <tr class="topic_value">
        <td>Direction id: </td>
        <td><select class="value" id="direction_id">
              <option>+</option>
              <option>1</option>
              <option>2</option>
            </select>
        </td>
      </tr>

      <tr class="topic_value">
        <td>Headsign: </td>
        <td><input class="value" id="headsign" type="text" value="+"></input></td>
      </tr>

      <tr class="topic_value">
        <td>Start time: </td>
        <td><input class="value" id="start_time" type="text" value="+"></input></td>
        <td class="validation_note">Time should be in format <code>hh:MM</code><td>
      </tr>

      <tr class="topic_value">
        <td>Next stop: </td>
        <td><input class="value" id="next_stop" type="text" value="+"></input></td>
        <td class="validation_note">Stop id should be 7 digits long<td>
      </tr>

      <tr class="topic_value">
        <td>Geohash level: </td>
        <td><select class="value" id="geohash_level">
              <option>0</option>
              <option>1</option>
              <option>2</option>
              <option>3</option>
              <option>4</option>
              <option>5</option>
              <option>+</option>
            </select></td>
          <td id="geohash_note"><b>Note:</b> Geohash level 0 shows only the most significant updates on the map</td>
      </tr>
    </table>

    <a id="show_topics" href="javascript:;" onclick="showTopics()">Show topics</a>
    <pre id="topics" style="display:none"></pre>

    <div id="map_container">
      <div><button class="geofilter" id="geohash_on">Use map bounds for geohash filter</button><button class="geofilter" id="geohash_off">Remove geohash filter</button></div>
      <br/>
      <div id="map"></div>
    </div>
    <script src="index.js"></script>
  </body>
</html>
result
console