RideLogicAVLS.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. var Feature = ol.Feature;
  2. var Map = ol.Map;
  3. var Overlay = ol.Overlay;
  4. var Point = ol.geom.Point;
  5. var TileJSON = ol.source.TileJSON;
  6. var VectorSource = ol.source.Vector;
  7. var View = ol.View;
  8. var Icon = ol.style.Icon;
  9. var Style = ol.style.Style;
  10. var TileLayer = ol.layer.Tile;
  11. var VectorLayer = ol.layer.Vector;
  12. var OSM = ol.source.OSM;
  13. var fromLonLat = ol.proj.fromLonLat;
  14. var LineString = ol.geom.LineString;
  15. //var defaultLonLat = [ -76.5019, 42.4440];
  16. //var defaultLonLat = [ -76.1805, 42.6012 ];
  17. var defaultLonLat = [ -76.2705, 42.5512 ];
  18. var defaultWebMerc = fromLonLat(defaultLonLat);
  19. function _rnd(a,b) {
  20. a = ((typeof a == "undefined") ? 1.0 : a);
  21. if (typeof b === "undefined") {
  22. return Math.random()*a;
  23. }
  24. return Math.random()*(b-a) + a;
  25. }
  26. function example_change_pos() {
  27. var w = 1/16.0;
  28. let lonlat = [
  29. defaultLonLat[0] + _rnd(-w,w),
  30. defaultLonLat[1] + _rnd(-w,w)];
  31. let merc = fromLonLat(lonlat);
  32. _icon[0].feature.getGeometry().setCoordinates(merc);
  33. busLayer.getSource().changed();
  34. }
  35. function example_change_opacity(p) {
  36. p = ((typeof p === "undefined") ? 0.0 : p);
  37. _icon[0].style.getImage().setOpacity(p);
  38. busLayer.getSource().changed();
  39. }
  40. // icon can't change image src dynamically,
  41. // so have to replace.
  42. // See https://stackoverflow.com/questions/57341190/how-can-i-change-icon-source-dynamically
  43. //
  44. function example_change_image() {
  45. var _nuimg = new Icon({
  46. anchor: [0.5, 46],
  47. anchorXUnits: 'fraction',
  48. anchorYUnits: 'pixels',
  49. src: 'data/bus_gw_90.png',
  50. });
  51. _icon[0].style.setImage(_nuimg);
  52. busLayer.getSource().changed();
  53. }
  54. //---
  55. //var vectorSource = new VectorSource({ features: [iconFeature], });
  56. var vectorSource = new VectorSource();
  57. var _icon = [];
  58. for (var ii=0; ii<2; ii++) {
  59. var w = 1/32.0;
  60. let lonlat = [
  61. defaultLonLat[0] + _rnd(-w,w),
  62. defaultLonLat[1] + _rnd(-w,w)];
  63. let merc = fromLonLat(lonlat);
  64. var iconFeature = new Feature({
  65. geometry: new Point([merc[0], merc[1]]),
  66. name: 'bus'
  67. });
  68. var iconStyle = new Style({
  69. image: new Icon({
  70. anchor: [0.5, 46],
  71. anchorXUnits: 'fraction',
  72. anchorYUnits: 'pixels',
  73. src: 'data/icon.png',
  74. }),
  75. });
  76. iconStyle.getImage().setOpacity(0.0);
  77. _icon.push({ "style": iconStyle, "feature": iconFeature });
  78. iconFeature.setStyle(iconStyle);
  79. vectorSource.addFeature(iconFeature);
  80. }
  81. //---
  82. const busLayer = new VectorLayer({
  83. source: vectorSource,
  84. zIndex: 2
  85. });
  86. //--
  87. const rasterLayer = new TileLayer({
  88. //source: ol.source.OSM()
  89. source: new ol.source.OSM(),
  90. });
  91. //--
  92. const map = new Map({
  93. //layers: [rasterLayer, vectorLayer, routeLayer],
  94. layers: [rasterLayer, busLayer ],
  95. target: document.getElementById('map'),
  96. view: new View({
  97. center: defaultWebMerc,
  98. zoom: 11,
  99. }),
  100. });
  101. const element = document.getElementById('popup');
  102. const popup = new Overlay({
  103. element: element,
  104. positioning: 'bottom-center',
  105. stopEvent: false,
  106. });
  107. map.addOverlay(popup);
  108. // display popup on click
  109. map.on('click', function (evt) {
  110. const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
  111. return feature;
  112. });
  113. });
  114. // change mouse cursor when over marker
  115. map.on('pointermove', function (e) {
  116. const pixel = map.getEventPixel(e.originalEvent);
  117. const hit = map.hasFeatureAtPixel(pixel);
  118. map.getTarget().style.cursor = hit ? 'pointer' : '';
  119. });
  120. // Close the popup when the map is moved
  121. map.on('movestart', function () {
  122. //$(element).popover('dispose');
  123. });
  124. map.on("postrender", function(event) {
  125. //console.log("bang...");
  126. });
  127. //----
  128. //
  129. setInterval( function() {
  130. //console.log("bang");
  131. //map.render();
  132. }, 1000);
  133. //-----
  134. //
  135. function update_buses(json_gtfs) {
  136. var bearingIdxLookup = [ "0", "45", "90", "135", "180", "225", "270", "315" ];
  137. for (let ii=0; ii<json_gtfs.entityList.length; ii++) {
  138. let id = json_gtfs.entityList[ii].id;
  139. let p = json_gtfs.entityList[ii].vehicle.position;
  140. let lat = p.latitude;
  141. let lon = p.longitude;
  142. let bearing = p.bearing;
  143. let lonlat = [ lon , lat ];
  144. let merc = fromLonLat(lonlat);
  145. if (typeof _icon[ii] === "undefined") { continue; }
  146. _icon[ii].feature.getGeometry().setCoordinates(merc);
  147. bearing = (bearing % 360 );
  148. if (bearing < 0) { bearing += 360.0; }
  149. let iheading = Math.floor( (parseInt( bearing ) + 23) / 45 );
  150. if (iheading > 7) { iheading = 0; }
  151. var _nuimg = new Icon({
  152. anchor: [0.5, 46],
  153. anchorXUnits: 'fraction',
  154. anchorYUnits: 'pixels',
  155. src: 'data/bus_gw_' + bearingIdxLookup[iheading] + '.png',
  156. });
  157. _icon[ii].style.setImage(_nuimg);
  158. _icon[ii].style.getImage().setOpacity(1.0);
  159. //console.log(">>", id, lat, lon, bearing);
  160. }
  161. busLayer.getSource().changed();
  162. }
  163. function fetch_gtfs_vehicle_position() {
  164. let xhr = new XMLHttpRequest();
  165. xhr.onload = function() {
  166. var ab = xhr.response;
  167. var json_pb = pb2json.pb2json(ab);
  168. //console.log(">>>", json_pb);
  169. update_buses(json_pb)
  170. };
  171. xhr.responseType = "arraybuffer";
  172. xhr.open("GET", "VehiclePosition.pb");
  173. xhr.send();
  174. }
  175. //--
  176. function update_route_layer(geojson) {
  177. if (!geojson) { return; }
  178. var route_points = geojson.features[0].geometry.coordinates;
  179. var merc_points = [];
  180. for (let ii=0; ii<route_points.length; ii++) {
  181. merc_points.push(ol.proj.transform(route_points[ii], 'EPSG:4326', 'EPSG:3857'));
  182. }
  183. var routeLine = new ol.Feature({
  184. geometry: new ol.geom.LineString(merc_points)
  185. });
  186. var routeLineVector = new ol.source.Vector({});
  187. routeLineVector.addFeature(routeLine);
  188. var routeLayer = new VectorLayer({
  189. source: routeLineVector,
  190. style: new ol.style.Style({
  191. fill: new ol.style.Fill({ color: 'rgb(0,0,255,0.25)', weight: 4, opacity: 0.5 }),
  192. stroke: new ol.style.Stroke({ color: 'rgb(0,0,255,0.25)', width: 6, opacity: 0.5 })
  193. }),
  194. zIndex: 0
  195. });
  196. map.addLayer(routeLayer);
  197. }
  198. function update_stop_layer(geojson) {
  199. if (!geojson) { return; }
  200. let stop_points = geojson.features[0].properties.route_stops;
  201. let merc_points = [];
  202. for (let ii=0; ii<stop_points.length; ii++) {
  203. console.log(stop_points[ii].stop);
  204. console.log(stop_points[ii].stop.geometry);
  205. console.log(stop_points[ii].stop.geometry.coordinates);
  206. let pnt = stop_points[ii].stop.geometry.coordinates;
  207. merc_points.push(ol.proj.transform(pnt, 'EPSG:4326', 'EPSG:3857'));
  208. }
  209. console.log("...");
  210. var stopVectorSource = new VectorSource();
  211. for (var ii=0; ii<merc_points.length; ii++) {
  212. let _stop = stop_points[ii].stop;
  213. let _stop_name = _stop.stop_name;
  214. console.log(merc_points[ii]);
  215. var iconFeature = new Feature({
  216. geometry: new Point([merc_points[ii][0], merc_points[ii][1]]),
  217. name: _stop_name
  218. });
  219. var iconStyle = new Style({
  220. image: new Icon({
  221. anchor: [0.5, 46],
  222. anchorXUnits: 'fraction',
  223. anchorYUnits: 'pixels',
  224. src: 'data/star-3.png',
  225. }),
  226. });
  227. iconStyle.getImage().setOpacity(0.8);
  228. iconFeature.setStyle(iconStyle);
  229. stopVectorSource.addFeature(iconFeature);
  230. }
  231. var stopLayer = new VectorLayer({
  232. source: stopVectorSource,
  233. zIndex: 0
  234. });
  235. map.addLayer(stopLayer);
  236. console.log(stop_points);
  237. }
  238. function fetch_geojson(url) {
  239. let xhr = new XMLHttpRequest();
  240. xhr.onload = function() {
  241. var geojson = xhr.response;
  242. update_route_layer(geojson);
  243. update_stop_layer(geojson);
  244. };
  245. xhr.responseType = "json";
  246. xhr.open("GET", url, true);
  247. xhr.send();
  248. }
  249. //--
  250. function _resize() {
  251. let h = $(window).height();
  252. let m = document.getElementById("map");
  253. m.style.height = (h-10) + "px";
  254. }
  255. function init() {
  256. setInterval(fetch_gtfs_vehicle_position, 1000);
  257. setTimeout( function() { fetch_geojson("geojson/test_route.geojson"); }, 100);
  258. $(window).on('resize', _resize);
  259. }
  260. init();