var markerConfigs = []; var crossroadConfigs = []; var ktdss; var map; // === Update ================================================================= function updateKtdsStates(data) { // markers data.watches.forEach((watch) => { const marker = markers[watch.id]; const pathUp = polylines[watch.id + "-UP"]; const pathDown = polylines[watch.id + "-DOWN"]; const markerConfig = markerConfigs[watch.id]; if (!marker || !markerConfig) { return; } const state = watch.data.state; const stateUp = markerConfig.direction == "left" ? watch.data.stateOut : watch.data.stateIn; const stateUpDesc = markerConfig.direction == "left" ? watch.data.stateOutDesc : watch.data.stateInDesc; const stateDown = markerConfig.direction == "left" ? watch.data.stateIn : watch.data.stateOut; const stateDownDesc = markerConfig.direction == "left" ? watch.data.stateInDesc : watch.data.stateOutDesc; // update marker if (marker) { const iconOptions = getIconOptions( state, stateUp, stateDown, markerConfig.direction, markerConfig.angle, watch.id ); marker.setIcon(L.icon(iconOptions)); } // update marker hint if (stateUpDesc) { markerConfig.hint = markerConfig.hint.replace( /()(.*?)(<\/span>)/, `$1${stateUpDesc}$3` ); } if (stateDownDesc) { markerConfig.hint = markerConfig.hint.replace( /()(.*?)(<\/span>)/, `$1${stateDownDesc}$3` ); } marker.setTooltipContent(markerConfig.hint); // update pathUp if (stateUp && pathUp) { pathUp.setStyle({ weight: 3, color: getStateColor(stateUp), }); } // update pathDown if (stateDown && pathDown) { pathDown.setStyle({ weight: 3, color: getStateColor(stateDown), }); } }); // crossroads data.crosses.forEach((cross) => { const marker = markers[cross.id]; const state = watch.data.state; const statedesc = watch.data.stateDesc; if (marker) { marker.setIcon(getIconOptions(state)); } if (statedesc) { markerConfig.hint.replace( /()(.*?)(<\/span>)/, "$" + statedesc + "$3" ); } // Areas TODO }); } // === Draw =================================================================== function getKtdsRoad(ktds) { const path = parsePathData(ktds.position_list); if (path) { return { coordinations: path, polylineOptions: { weight: 6, opacity: 0.75, color: "#72726F", }, }; } return null; } function getKtdsMarker(markerData) { const pathUp = parsePathData(markerData.gpsListUp); const pathDown = parsePathData(markerData.gpsListDown); // angle var path = pathUp ? pathUp : pathDown; var angle = null; if (path && path.length > 1) { angle = countAzimuth( path[0].lat, path[0].lng, path[1].lat, path[1].lng ); } // marker var markerOptions = { coordinations: [markerData.position_lat, markerData.position_lng], icon: setIcon( getIconOptions( markerData.state, markerData.stateUp, markerData.stateDown, markerData.direction, angle, markerData.id ) ), tooltip: true, tooltipContent: markerData.hint, }; // paths var pathUpOptions = getSimplePath(pathUp, markerData.stateUp); var pathDownOptions = getSimplePath(pathDown, markerData.stateDown); markerConfigs[markerData.id] = { direction: markerData.direction, angle: angle, hint: markerData.hint, }; return { markerOptions, pathUpOptions, pathDownOptions }; } function getKtdsCrossroad(crossroadData) { // marker var markerOptions = { coordinations: [crossroadData.position_lat, crossroadData.position_lng], icon: setIcon(getIconOptions(crossroadData.state)), tooltip: true, tooltipContent: crossroadData.hint, }; // areas const areasOptions = []; for (const areaId in crossroadData.areas) { const area = crossroadData.areas[areaId]; const pathCoords = parsePathData(area.polyline); areasOptions.push(getSimplePolygon(pathCoords, area.state)); } markerConfigs[crossroadData.id] = { hint: crossroadData.hint, }; return { markerOptions, areasOptions }; } // === Utils ================================================================== function getSimplePath(coords, state) { if (coords) { return { coordinations: coords, polylineOptions: { weight: 3, color: getStateColor(state), }, }; } return null; } function getSimplePolygon(coords, state) { if (coords) { const color = getStateColor(state); return { coordinations: coords, polygonOptions: { weight: 4, color: color, fillColor: color, }, }; } return null; } function parsePathData(jsonPathData) { if (!jsonPathData) { return null; } if (jsonPathData.includes("\\")) { jsonPathData = jsonPathData.replace(/\\/g, ""); } const parsedData = JSON.parse(jsonPathData); return parsedData._stack.map((coord) => ({ lat: parseFloat(coord._lat), lng: parseFloat(coord._lng), })); } function getStateColor(state) { switch (state) { case "traffic_normal": return "#00923f"; case "traffic_occupied": return "#ff6600"; case "traffic_before_congestion": return "#ff6600"; case "traffic_after_congestion": return "#fff500"; case "traffic_congestion": return "#da251d"; case "alg_calibrating": return "#99ccff"; case "alg_no_preposition": return "#6f98cc"; case "alg_off": return "#996600"; case "other": return "#72726F"; default: return "#72726F"; } } function getIconOptions(state, stateUp, stateDown, direction, angle, id) { var iconUrl = BASE_URL + "/public/images/circles/circle-gray.png"; if (stateUp && stateDown) { const top = direction == "left" ? stateDown : stateUp; const down = direction != "left" ? stateDown : stateUp; if (angle == null) { angle = 0; } iconUrl = BASE_URL + "/public/ktds/status-icon/?top=" + top + "&down=" + down + "&orientation=" + angle + "&watch=" + id; } else if (stateUp) { iconUrl = getStateImageUrl(stateUp); } else if (stateDown) { iconUrl = getStateImageUrl(stateDown); } else if (state) { iconUrl = getStateImageUrl(state); } return { iconUrl: iconUrl, iconSize: [20, 20], iconAnchor: [10, 10], tooltipAnchor: [0, 0], }; } function getStateImageUrl(state) { switch (state) { case "traffic_normal": return BASE_URL + "/public/images/circles/circle-green.png"; case "traffic_occupied": return BASE_URL + "/public/images/circles/circle-orange.png"; case "traffic_before_congestion": return BASE_URL + "/public/images/circles/circle-orange.png"; case "traffic_after_congestion": return BASE_URL + "/public/images/circles/circle-yellow.png"; case "traffic_congestion": return BASE_URL + "/public/images/circles/circle-red.png"; case "alg_calibrating": return BASE_URL + "/public/images/circles/circle-light-blue.png"; case "alg_no_preposition": return BASE_URL + "/public/images/circles/circle-child-blue.png"; case "alg_off": return BASE_URL + "/public/images/circles/circle-brown.png"; case "other": return BASE_URL + "/public/images/circles/circle-gray.png"; default: return BASE_URL + "/public/images/circles/circle-gray.png"; } } // === Filter ================================================================= function toggleWindowTab(thisElement) { if ($("windowBody").style.display == "none") { $("windowBody").style.display = ""; thisElement.style.backgroundColor = "#FFFFFF"; thisElement.querySelector("img").src = BASE_URL + "/public/images/map/arrow-close.png"; } else { $("windowBody").style.display = "none"; thisElement.style.backgroundColor = "#EEEEEE"; thisElement.querySelector("img").src = BASE_URL + "/public/images/map/arrow-open.png"; } } function preventFilterWindowEvents() { var window = document.getElementById("window"); L.DomEvent.disableScrollPropagation(window); L.DomEvent.disableClickPropagation(window); } function redrawMap() { var rows = $("windowBody").querySelector("table tbody").rows; for (let i = 0; i < rows.length; i++) { var input = rows[i].querySelector("input"); const ktds = ktdss[input.name]; // polyline if (polylines[ktds.id]) { setLayerVisibility(polylines[ktds.id], input.checked); } // markers ktds.markers.forEach((marker) => { setLayerVisibility(markers[marker.id], input.checked); if (marker.gpsListUp) { setLayerVisibility(polylines[marker.id + "-UP"], input.checked); } if (marker.gpsListDown) { setLayerVisibility( polylines[marker.id + "-DOWN"], input.checked ); } }); // crossroads ktds.crossroads.forEach((crossroad) => { if (markers[crossroad.id]) { setLayerVisibility(markers[crossroad.id], input.checked); } var i = 0; for (const areaId in crossroad.areas) { const area = crossroad.areas[areaId]; if (area.polyline && polygons[crossroad.id + "-A" + i]) { setLayerVisibility( polygons[crossroad.id + "-A" + i], input.checked ); } i++; } }); } } function setLayerVisibility(layer, show) { if (show && !map.hasLayer(layer)) { map.addLayer(layer); } if (!show && map.hasLayer(layer)) { map.removeLayer(layer); } }