SpeedLimitSection/utils/milepostsUtil.ts

src/ui/components/widgets/SpeedLimitSection/utils/milepostsUtil.ts
 avatar
unknown
typescript
5 months ago
5.8 kB
4
Indexable
import _ from 'lodash'
import { SpeedLimitType, StatusTypes } from '../types'

export const checkOverlapMileposts = (
  newSpeedLimit: any,
  existingSpeedLimits: any[],
  subdivision: string,
  idSpeedLimitItem?: string
): boolean => {
  // Get the speed limits within the same subdivision
  const speedLimitsOfSameDivision = existingSpeedLimits?.filter(
    item =>
      item?.subdivision === subdivision &&
      item?.temporary_speed_limit_id !== idSpeedLimitItem
  )

  // Append the new speed limit to the existing speed limit
  const newSpeedLimits = [
    ...speedLimitsOfSameDivision,
    { start_mile: newSpeedLimit.startMile, end_mile: newSpeedLimit.endMile }
  ]

  // Normalize the new speed limits
  let normalizedSpeedLimits = newSpeedLimits.map(speedLimit => {
    if (speedLimit.start_mile > speedLimit.end_mile) {
      return {
        start_mile: speedLimit.end_mile,
        end_mile: speedLimit.start_mile
      }
    }
    return speedLimit
  })

  // Sort speed limits by start mile
  normalizedSpeedLimits.sort((a, b) => a.start_mile - b.start_mile)

  // Check for overlaps
  for (let i = 0; i < normalizedSpeedLimits.length - 1; i++) {
    if (
      normalizedSpeedLimits[i].end_mile >
      normalizedSpeedLimits[i + 1].start_mile
    ) {
      return false
    }
  }

  return true
}

export const findOverlappingMileposts = (
  newSpeedLimit: { startMile: number; endMile: number },
  existingSpeedLimits: any[],
  subdivision: string,
  type: SpeedLimitType,
  idSpeedLimitItem?: string
) => {
  const speedLimitsOfSameDivision = existingSpeedLimits?.filter(
    item =>
      item?.subdivision === subdivision &&
      item?.type === type &&
      item?.temporary_speed_limit_id !== idSpeedLimitItem &&
      item?.newId !== idSpeedLimitItem &&
      item?.status !== StatusTypes.Delete
  )

  const newSpeedLimits = [
    ...speedLimitsOfSameDivision,
    { start_mile: newSpeedLimit.startMile, end_mile: newSpeedLimit.endMile }
  ]

  const normalizedSpeedLimits = newSpeedLimits.map(speedLimit => ({
    id: speedLimit?.temporary_speed_limit_id || speedLimit?.newId,
    start_mile: Math.min(
      speedLimit.new_start_mile
        ? speedLimit?.new_start_mile
        : speedLimit?.start_mile,
      speedLimit.new_end_mile ? speedLimit?.new_end_mile : speedLimit?.end_mile
    ),
    end_mile: Math.max(
      speedLimit.new_start_mile
        ? speedLimit?.new_start_mile
        : speedLimit?.start_mile,
      speedLimit.new_end_mile ? speedLimit?.new_end_mile : speedLimit?.end_mile
    )
  }))
  console.log(
    '🚀 ~ normalizedSpeedLimits ~ normalizedSpeedLimits:',
    normalizedSpeedLimits
  )

  normalizedSpeedLimits.sort((a, b) => a.start_mile - b.start_mile)

  let overlappingIds: string[] = []

  for (let i = 0; i < normalizedSpeedLimits.length - 1; i++) {
    for (let j = i + 1; j < normalizedSpeedLimits.length; j++) {
      const start = Math.max(
        normalizedSpeedLimits[i].start_mile,
        normalizedSpeedLimits[j].start_mile
      )
      const end = Math.min(
        normalizedSpeedLimits[i].end_mile,
        normalizedSpeedLimits[j].end_mile
      )

      if (
        start < end ||
        (start === end &&
          ((start > normalizedSpeedLimits[i].start_mile &&
            start < normalizedSpeedLimits[i].end_mile) ||
            (start > normalizedSpeedLimits[j].start_mile &&
              start < normalizedSpeedLimits[j].end_mile)))
      ) {
        if (normalizedSpeedLimits[i].id) {
          overlappingIds.push(normalizedSpeedLimits[i].id)
        }
        if (normalizedSpeedLimits[j].id) {
          overlappingIds.push(normalizedSpeedLimits[j].id)
        }
      }
    }
  }

  const foundIndices = existingSpeedLimits
    ?.map((item, index) =>
      overlappingIds?.includes(
        item?.temporary_speed_limit_id || item?.newId || ''
      )
        ? index
        : -1
    )
    .filter(index => index !== -1)

  return [...new Set(foundIndices)]
}

export const checkInvalidMileposts = (
  newSpeedLimit: { startMile: number; endMile: number },
  startLimit: string,
  endLimit: string
): boolean => {
  const { startMile, endMile } = newSpeedLimit
  const startLimitNum = Number(startLimit)
  const endLimitNum = Number(endLimit)

  if (startMile === undefined || endMile === undefined) {
    return true
  }

  return !(
    (startLimitNum < endLimitNum &&
      startMile <= endMile &&
      startMile >= startLimitNum &&
      endMile <= endLimitNum) ||
    (startLimitNum > endLimitNum &&
      startMile >= endMile &&
      startMile <= startLimitNum &&
      endMile >= endLimitNum)
  )
}

export const getWholeMileposts = (trackCoordinatesData: any[]) => {
  // Get unique track coords by milepost and lat, lng
  const uniqueTrackCoords = _.uniqBy(trackCoordinatesData, coord =>
    [
      coord.milepost,
      coord.gps_coordinates.lat,
      coord.gps_coordinates.lng
    ].join()
  )
  const wholeMilepostTrackCoords = uniqueTrackCoords.filter(
    (coord: any) => coord.milepost % 10 === 0
  )
  return wholeMilepostTrackCoords
}

export const findMaxTSOLimit = (
  zones: any[],
  tso: any,
  subdivision: string
) => {
  const zoneSpeedLimitsOfSameDivision = zones?.filter(
    item => item?.subdivision === subdivision
  )

  const overlappingZones = zoneSpeedLimitsOfSameDivision.filter(zone => {
    if (tso.start < tso.end)
      return tso.end > zone.start_mile && tso.start < zone.end_mile
    return tso.end < zone.start_mile && tso.start > zone.end_mile
  })

  const minLimit = Math.min(
    ...overlappingZones.map(zone => zone.speed_limit_mph)
  )

  return minLimit
}
Editor is loading...
Leave a Comment