diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 0000000..bad1a85
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,69 @@
+#-------------------------------------------------------------------------------------------------------------
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
+#-------------------------------------------------------------------------------------------------------------
+
+FROM eclipse-temurin:21-jdk
+
+# This Dockerfile adds a non-root user with sudo access. Use the "remoteUser"
+# property in devcontainer.json to use it. On Linux, the container user's GID/UIDs
+# will be updated to match your local UID/GID (when using the dockerFile property).
+# See https://aka.ms/vscode-remote/containers/non-root-user for details.
+ARG USERNAME=vscode
+ARG USER_UID=1234
+ARG USER_GID=$USER_UID
+
+# Configure apt
+ENV DEBIAN_FRONTEND=noninteractive
+RUN apt-get update
+RUN apt-get upgrade -y
+RUN apt-get -y install --no-install-recommends apt-utils dialog 2>&1
+
+# Create a non-root user to use if preferred - see https://aka.ms/vscode-remote/containers/non-root-user.
+RUN groupadd --gid $USER_GID $USERNAME
+RUN useradd -s /bin/bash --uid $USER_UID --gid $USER_GID -m $USERNAME
+# [Optional] Add sudo support for the non-root user
+RUN apt-get install -y sudo
+RUN echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME
+RUN chmod 0440 /etc/sudoers.d/$USERNAME
+
+# Verify git, needed tools installed
+RUN apt-get -y install git openssh-client less iproute2 procps curl lsb-release zip unzip sed kafkacat telnet
+
+#-------------------Install SDKMan----------------------------------
+RUN curl -s https://get.sdkman.io | bash
+RUN chmod a+x "$HOME/.sdkman/bin/sdkman-init.sh"
+#-------------------------------------------------------------------------------------------------------------
+
+#-------------------Install Maven CLI Tools----------------------------------
+ARG MAVEN_VERSION=3.6.3
+RUN /bin/bash -c "source $HOME/.sdkman/bin/sdkman-init.sh && sdk install maven ${MAVEN_VERSION}"
+#-------------------------------------------------------------------------------------------------------------
+
+# Install snmp (rsu-data-controller dependency)
+RUN apt-get -y install snmp
+
+#-------------------Install Kafka----------------------------------
+RUN mkdir ~/Downloads
+RUN curl "https://archive.apache.org/dist/kafka/3.6.1/kafka_2.12-3.6.1.tgz" -o ~/Downloads/kafka.tgz
+RUN mkdir ~/kafka \
+ && cd ~/kafka \
+ && tar -xvzf ~/Downloads/kafka.tgz --strip 1
+RUN echo "\nadvertised.listeners=PLAINTEXT://localhost:9092" >> ~/kafka/config/server.properties
+#-------------------------------------------------------------------------------------------------------------
+
+# Clean up
+RUN apt-get autoremove -y \
+ && apt-get clean -y \
+ && rm -rf /var/lib/apt/lists/*
+ENV DEBIAN_FRONTEND=dialog
+
+# Allow for a consistant java home location for settings - image is changing over time
+RUN if [ ! -d "/docker-java-home" ]; then ln -s "${JAVA_HOME}" /docker-java-home; fi
+
+COPY kafka /etc/init.d/kafka
+RUN chmod 775 /etc/init.d/kafka && update-rc.d kafka defaults
+
+COPY ./docker-entrypoint.sh ./docker-entrypoint.sh
+RUN chmod +x ./docker-entrypoint.sh
+ENTRYPOINT ["./docker-entrypoint.sh"]
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 0000000..d808b0e
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,38 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
+// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.0/containers/java-8
+{
+ "name": "JPO Deduplicator Java 21",
+ "dockerFile": "Dockerfile",
+ "overrideCommand": false,
+ "shutdownAction": "stopContainer",
+ "customizations": {
+ "vscode": {
+ "settings": {
+ "terminal.integrated.shell.linux": "/bin/bash"
+ },
+ "extensions": [
+ "vscjava.vscode-java-pack",
+ "vscjava.vscode-java-debug",
+ "vscjava.vscode-maven",
+ "vscjava.vscode-java-dependency",
+ "vscjava.vscode-java-test",
+ "hbenl.vscode-test-explorer",
+ "ms-vscode.test-adapter-converter",
+ "esbenp.prettier-vscode",
+ "mhutchie.git-graph",
+ "tabnine.tabnine-vscode",
+ "redhat.java",
+ "redhat.vscode-commons"
+ ]
+ }
+ },
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [8080, 9090, 46753, 46800, 5555, 6666, 8090, 2181, 9092],
+ // Use 'postCreateCommand' to run commands after the container is created.
+ "postCreateCommand": "bash .devcontainer/post-create.sh",
+ // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
+ // "remoteUser": "vscode"
+ "runArgs": [
+ "--network=host"
+ ]
+}
\ No newline at end of file
diff --git a/.devcontainer/docker-entrypoint.sh b/.devcontainer/docker-entrypoint.sh
new file mode 100644
index 0000000..a294d8b
--- /dev/null
+++ b/.devcontainer/docker-entrypoint.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+
+trap stop SIGTERM SIGINT SIGQUIT SIGHUP ERR
+
+start() {
+ echo "Container started, starting kafka..." >>/root/startup.txt
+ sudo service kafka start
+}
+
+stop() {
+ echo "Container stopped, performing cleanup..." >>/root/shutdown.txt
+ sudo service kafka stop
+ sleep 2
+ exit 0
+}
+
+start
+
+while
+ sleep 1 &
+ wait $!
+do :; done
diff --git a/.devcontainer/jpo-deduplicator.code-workspace b/.devcontainer/jpo-deduplicator.code-workspace
new file mode 100644
index 0000000..998bc22
--- /dev/null
+++ b/.devcontainer/jpo-deduplicator.code-workspace
@@ -0,0 +1,11 @@
+{
+ "folders": [
+ {
+ "path": "."
+ }
+ ],
+ "settings": {
+ "java.configuration.updateBuildConfiguration": "automatic",
+ "java.server.launchMode": "Standard"
+ }
+}
\ No newline at end of file
diff --git a/.devcontainer/kafka b/.devcontainer/kafka
new file mode 100644
index 0000000..be2be98
--- /dev/null
+++ b/.devcontainer/kafka
@@ -0,0 +1,36 @@
+DAEMON_PATH=/root/kafka
+PATH=$PATH:$DAEMON_PATH/bin
+PATH=$PATH:/root/.sdkman/candidates/java/current/bin
+
+export LOG_DIR=/var/log/kafka
+
+# See how we were called.
+case "$1" in
+ start)
+ # Start daemon.
+ echo "Starting Kafka";
+ $DAEMON_PATH/bin/kafka-server-start.sh -daemon $DAEMON_PATH/config/server.properties
+ ;;
+ stop)
+ # Stop daemons.
+ echo "Shutting down Kafka";
+ $DAEMON_PATH/bin/kafka-server-stop.sh
+ ;;
+ restart)
+ $0 stop
+ sleep 2
+ $0 start
+ ;;
+ status)
+ pid=`ps ax | grep -i 'kafka.Kafka' | grep -v grep | awk '{print $1}'`
+ if [ -n "$pid" ]
+ then
+ echo "Kafka is Running as PID: $pid"
+ else
+ echo "Kafka is not Running"
+ fi
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|status}"
+ exit 1
+esac
\ No newline at end of file
diff --git a/.devcontainer/post-create.sh b/.devcontainer/post-create.sh
new file mode 100644
index 0000000..b54a6a5
--- /dev/null
+++ b/.devcontainer/post-create.sh
@@ -0,0 +1,30 @@
+cd ~/kafka/
+KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
+
+bin/kafka-storage.sh format -t $KAFKA_CLUSTER_ID -c config/kraft/server.properties
+
+# start kafka
+bin/kafka-server-start.sh -daemon config/kraft/server.properties
+# wait 2 seconds for the server to start and be able to add partitions
+sleep 2s
+# add topics
+
+# MAP
+bin/kafka-topics.sh --create --topic "topic.OdeMapJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedOdeMapJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.ProcessedMap" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedProcessedMap" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+
+# SPaT
+bin/kafka-topics.sh --create --topic "topic.OdeSpatJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedOdeSpatJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.ProcessedSpat" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedProcessedSpat" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+
+# BSM
+bin/kafka-topics.sh --create --topic "topic.OdeBsmJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedOdeBsmJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+
+# TIM
+bin/kafka-topics.sh --create --topic "topic.OdeTimJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
+bin/kafka-topics.sh --create --topic "topic.DeduplicatedOdeTimJson" --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1
diff --git a/.github/workflows/artifact-publish.yml b/.github/workflows/artifact-publish.yml
new file mode 100644
index 0000000..8ef378f
--- /dev/null
+++ b/.github/workflows/artifact-publish.yml
@@ -0,0 +1,48 @@
+name: Publish Java Package
+
+on:
+ push:
+ branches:
+ - "develop"
+ - "master"
+ - "release/*"
+
+
+jobs:
+ deduplicator-publish:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Set up JDK 21a
+ uses: actions/setup-java@v4
+ with:
+ java-version: '21'
+ distribution: 'temurin'
+
+ - name: Remove snapshot from version
+ run: |
+ cd jpo-deduplicator
+ mvn versions:set -DremoveSnapshot
+
+ - name: Build with Maven
+ env:
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ MAVEN_GITHUB_TOKEN_NAME: ${{ vars.MAVEN_GITHUB_TOKEN_NAME }}
+ MAVEN_GITHUB_TOKEN: ${{ secrets.MAVEN_GITHUB_TOKEN }}
+ MAVEN_GITHUB_ORG: ${{ github.repository_owner }}
+ run: |
+ cd jpo-deduplicator
+ mvn -s settings.xml -B package --file pom.xml -DskipTests -Ppackage-jar
+
+ - name: Publish to GitHub Packages
+ run: |
+ cd jpo-deduplicator
+ mvn -s settings.xml --batch-mode -Dgithub_organization=${{ github.repository_owner }} deploy -DskipTests -Ppackage-jar
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ MAVEN_GITHUB_TOKEN_NAME: ${{ vars.MAVEN_GITHUB_TOKEN_NAME }}
+ MAVEN_GITHUB_TOKEN: ${{ secrets.MAVEN_GITHUB_TOKEN }}
+ MAVEN_GITHUB_ORG: ${{ github.repository_owner }}
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..51b81c7
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,30 @@
+name: CI
+
+on:
+ pull_request:
+ paths:
+ - 'jpo-deduplicator/**'
+
+
+
+jobs:
+ deduplicator-test:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Set up JDK
+ uses: actions/setup-java@v4
+ with:
+ java-version: "21"
+ distribution: "temurin"
+ cache: 'maven'
+
+ - name: Run tests
+ env:
+ MAVEN_GITHUB_TOKEN: ${{ secrets.MAVEN_GITHUB_TOKEN }}
+ MAVEN_GITHUB_ORG: ${{ github.repository_owner }}
+ run: |
+ cd $GITHUB_WORKSPACE/jpo-deduplicator
+ mvn verify -s ./settings.xml
\ No newline at end of file
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 0000000..d4808d5
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,26 @@
+name: Docker build
+
+on:
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+jobs:
+ jpo-deduplicator:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+ - name: Build
+ uses: docker/build-push-action@v3
+ with:
+ context: .
+ build-args: |
+ MAVEN_GITHUB_TOKEN_NAME=${{ vars.MAVEN_GITHUB_TOKEN_NAME }}
+ MAVEN_GITHUB_TOKEN=${{ secrets.MAVEN_GITHUB_TOKEN }}
+ MAVEN_GITHUB_ORG=${{ github.repository_owner }}
+ secrets: |
+ MAVEN_GITHUB_TOKEN: ${{ secrets.MAVEN_GITHUB_TOKEN }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
\ No newline at end of file
diff --git a/.github/workflows/dockerhub.yml b/.github/workflows/dockerhub.yml
new file mode 100644
index 0000000..ea71cb3
--- /dev/null
+++ b/.github/workflows/dockerhub.yml
@@ -0,0 +1,41 @@
+name: "DockerHub Build and Push"
+
+on:
+ push:
+ branches:
+ - "develop"
+ - "master"
+ - "release/*"
+
+jobs:
+ dockerhub-jpo-deduplicator:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+ - name: Login to DockerHub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Replcae Docker tag
+ id: set_tag
+ run: echo "TAG=$(echo ${GITHUB_REF##*/} | sed 's/\//-/g')" >> $GITHUB_ENV
+
+ - name: Build
+ uses: docker/build-push-action@v3
+ with:
+ context: .
+ push: true
+ tags: usdotjpoode/jpo-deduplicator:${{ env.TAG }}
+ build-args: |
+ MAVEN_GITHUB_TOKEN_NAME=${{ vars.MAVEN_GITHUB_TOKEN_NAME }}
+ MAVEN_GITHUB_TOKEN=${{ secrets.MAVEN_GITHUB_TOKEN }}
+ MAVEN_GITHUB_ORG=${{ github.repository_owner }}
+ secrets: |
+ MAVEN_GITHUB_TOKEN: ${{ secrets.MAVEN_GITHUB_TOKEN }}
+ cache-from: type=gha
+ cache-to: type=gha,mode=max
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8d161e5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+**/.env
+
+**/target
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..532f96c
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "jpo-utils"]
+ path = jpo-utils
+ url = https://github.com/usdot-jpo-ode/jpo-utils.git
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..53f13e6
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ "recommendations": [
+ "redhat.vscode-xml",
+ "vscjava.vscode-java-pack",
+ "redhat.java",
+ "vmware.vscode-boot-dev-pack"
+ ]
+}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..49e558c
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,56 @@
+FROM maven:3.8-eclipse-temurin-21-alpine AS builder
+
+WORKDIR /home
+
+ARG MAVEN_GITHUB_TOKEN
+ARG MAVEN_GITHUB_ORG
+
+ENV MAVEN_GITHUB_TOKEN=$MAVEN_GITHUB_TOKEN
+ENV MAVEN_GITHUB_ORG=$MAVEN_GITHUB_ORG
+
+RUN test -n "$MAVEN_GITHUB_TOKEN" || (echo "Error: MAVEN_GITHUB_TOKEN cannot be empty" && exit 1)
+RUN test -n "$MAVEN_GITHUB_ORG" || (echo "Error: MAVEN_GITHUB_ORG cannot be empty" && exit 1)
+
+# Copy and Build Deduplicator
+WORKDIR /home
+COPY ./jpo-deduplicator/pom.xml ./jpo-deduplicator/
+COPY ./jpo-deduplicator/settings.xml ./jpo-deduplicator/
+
+WORKDIR /home/jpo-deduplicator
+RUN mvn -s settings.xml dependency:resolve
+
+COPY ./jpo-deduplicator/src ./src
+RUN mvn -s settings.xml install -DskipTests
+
+FROM amazoncorretto:21
+
+WORKDIR /home
+
+COPY --from=builder /home/jpo-deduplicator/src/main/resources/application.yaml /home
+COPY --from=builder /home/jpo-deduplicator/src/main/resources/logback.xml /home
+COPY --from=builder /home/jpo-deduplicator/target/jpo-deduplicator.jar /home
+
+#COPY cert.crt /home/cert.crt
+#RUN keytool -import -trustcacerts -keystore /usr/local/openjdk-11/lib/security/cacerts -storepass changeit -noprompt -alias mycert -file cert.crt
+
+RUN amazon-linux-extras install -y epel && \
+ yum install -y jemalloc-devel
+ENV LD_PRELOAD="/usr/lib64/libjemalloc.so"
+
+ENTRYPOINT ["java", \
+ "-Djava.rmi.server.hostname=$DOCKER_HOST_IP", \
+ "-Dlogback.configurationFile=/home/logback.xml", \
+ "-Xmx1024M", \
+ "-Xms128M", \
+ "-XX:+UseG1GC", \
+ "-XX:MaxGCPauseMillis=20", \
+ "-XX:InitiatingHeapOccupancyPercent=35", \
+ "-XX:MetaspaceSize=96m", \
+ "-XX:MinMetaspaceFreeRatio=50", \
+ "-XX:MaxMetaspaceFreeRatio=80", \
+ "-XX:+ExplicitGCInvokesConcurrent", \
+ "-XX:InitialRAMPercentage=5.0", \
+ "-jar", \
+ "/home/jpo-deduplicator.jar"]
+
+# ENTRYPOINT ["tail", "-f", "/dev/null"]
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..d080e5c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,48 @@
+default:
+ $(info Make target options:)
+ $(info `make start` to run the deduplicator)
+ $(info `make build` to build the deduplicator)
+ $(info `make stop` to stop the deduplicator)
+ $(info `make delete` to stop the deduplicator and remove the volumes)
+ $(info `make restart` to stop and then start the deduplicator)
+ $(info `make rebuild` to stop, delete, and then rebuild the containers)
+ $(info `make clean-build` to rebuild the containers without using the cache)
+
+.PHONY: start
+start:
+ifeq ("$(wildcard .env)", "")
+ $(error "ERROR: deduplicator Environment file `.env` not found in ${PWD}")
+endif
+ifeq ("$(wildcard ./jpo-utils/.env)", "")
+ $(error "ERROR: jpo-utils Environment file `.env` not found in ${PWD}")
+endif
+ docker compose up -d
+
+build:
+ifeq ("$(wildcard .env)", "")
+ $(error "ERROR: jpo-ode Environment file `.env` not found in ${PWD}")
+endif
+ifeq ("$(wildcard ./jpo-utils/.env)", "")
+ $(error "ERROR: jpo-utils Environment file `.env` not found in ${PWD}")
+endif
+ docker compose build
+
+.PHONY: stop
+stop:
+ docker compose down
+
+.PHONY: delete
+delete:
+ docker compose down -v
+
+.PHONY: restart
+restart:
+ $(MAKE) stop start
+
+.PHONY: rebuild
+rebuild:
+ $(MAKE) stop delete build start
+
+.PHONY: clean-build
+clean-build:
+ docker compose build --no-cache
\ No newline at end of file
diff --git a/README.md b/README.md
index a231a3d..983dec0 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,170 @@
-# jpo-deduplicator
\ No newline at end of file
+
+# jpo-deduplicator
+
+**US Department of Transportation (USDOT) Intelligent Transportation Systems (ITS) Joint Program Office (JPO) Message Deduplicator**
+
+The JPO-Deduplicator is a Kafka Java spring-boot application designed to reduce the number of messages stored and processed in the ODE system. This is done by reading in messages from an input topic (such as topic.ProcessedMap) and outputting a subset of those messages on a related output topic (topic.DeduplicatedProcessedMap). Functionally, this is done by removing deduplicate messages from the input topic and only passing on unique messages. In addition, each topic will pass on at least 1 message per hour even if the message is a duplicate. This behavior helps ensure messages are still flowing through the system.
+
+The following topics currently support deduplication.
+
+- topic.ProcessedMap -> topic.DeduplicatedProcessedMap
+- topic.ProcessedMapWKT -> topic.DeduplicatedProcessedMapWKT
+- topic.OdeMapJson -> topic.DeduplicatedOdeMapJson
+- topic.OdeTimJson -> topic.DeduplicatedOdeTimJson
+- topic.OdeRawEncodedTIMJson -> topic.DeduplicatedOdeRawEncodedTIMJson
+- topic.OdeBsmJson -> topic.DeduplicatedOdeBsmJson
+- topic.ProcessedSpat -> topic.DeduplicatedProcessedSpat
+
+## Release Notes
+
+The current version and release history of the JPO Deduplicator: [Release Notes]()
+
+
+
+## Table of Contents
+
+- [jpo-deduplicator](#jpo-deduplicator)
+ - [Release Notes](#release-notes)
+ - [Table of Contents](#table-of-contents)
+ - [1. System Requirements](#1-system-requirements)
+ - [2. Usage Example](#2-usage-example)
+ - [3. Configuration](#3-configuration)
+ - [Software Prerequisites](#software-prerequisites)
+ - [Feature Flags](#feature-flags)
+ - [Generate a Github Token](#generate-a-github-token)
+ - [4. Development Setup](#4-development-setup)
+ - [Integrated Development Environment (IDE)](#integrated-development-environment-ide)
+ - [5. Contact Information](#5-contact-information)
+ - [License information](#license-information)
+ - [6. Contributing](#6-contributing)
+
+
+
+## 1. System Requirements
+
+Recommended machine specs running Docker to run the JPO-Deduplicator:
+
+- Minimum RAM: 16 GB
+
+- Minimum storage space: 100 GB
+- Supported operating systems:
+
+ - Ubuntu 20.04 Linux (Recommended)
+ - Windows 10/11 Professional (Professional version required for Docker virtualization)
+ - OSX 10 Mojave
+
+The JPO-Deduplicator software can run on most standard Window, Mac, or Linux based computers with
+Pentium core processors. Performance of the software will be based on the computing power and available RAM in
+the system. Larger data flows can require much larger space requirements depending on the amount of data being processed by the software. The JPO-Deduplicator software application was developed using the open source programming language Java. If running the JPO-Deduplicator outside of Docker, the application requires the Java 21 runtime environment.
+
+[Back to top](#table-of-contents)
+
+
+
+## 2. Usage Example
+
+1. Create a copy of `sample.env` and rename it to `.env`.
+2. Create a copy of the `jpo-utils/sample.env` file and rename it to `.env` in the `jpo-utils` directory.
+3. Update the variable `MAVEN_GITHUB_TOKEN` in the root `.env` file to a github token used for downloading jar file dependencies. For full instructions on how to generate a token please see [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages).
+4. Navigate back to the root directory and run the following command: `make build`
+ 1. Make sure that you have [docker-compose](https://docs.docker.com/compose/install/) and [make](https://www.gnu.org/software/make/manual/make.html) installed.
+5. Run the following command: `make start`
+6. Produce a sample message to one of the sink topics by using `kafka_ui` by:
+ 1. Go to `localhost:8001`
+ 2. Click local -> Topics
+ 3. Select `topic.OdeMapJson`
+ 4. Select `Produce Message`
+ 5. Copy in sample JSON for a Map Message
+ 6. Click `Produce Message` multiple times
+7. View the synced message in `kafka_ui` by:
+ 1. Go to `localhost:8001`
+ 2. Click local -> Topics
+ 3. Select `topic.DeduplicatedOdeMapJson`
+ 4. You should now see only one copy of the map message sent.
+
+[Back to top](#table-of-contents)
+
+
+
+## 3. Configuration
+
+### Software Prerequisites
+
+The JPO-Deduplicator is a micro service that runs as an independent application but serves the sole purpose of deduplicating JSON objects created by the JPO-ODE via Apache Kafka. To support these JSON objects, the JPO-Deduplicator application utilizes some classes from the JPO-ODE, JPO-GeojsonConverter, and the JPO-ConflictMonitor. These classes are referenced in the JPO-Deduplicator by pulling the built `.jar` artifact from GitHub Maven Central. All other required dependencies will automatically be downloaded and installed as part of the Docker build process.
+
+- Docker:
+- Docker-Compose:
+
+### Feature Flags
+
+To manually configure deduplication for a topic, the following environment variables can also be used.
+
+| Environment Variable | Description |
+|---|---|
+| `ENABLE_PROCESSED_MAP_DEDUPLICATION` | `true` / `false` - Enable ProcessedMap message Deduplication |
+| `ENABLE_PROCESSED_MAP_WKT_DEDUPLICATION` | `true` / `false` - Enable ProcessedMap WKT message Deduplication |
+| `ENABLE_ODE_MAP_DEDUPLICATION` | `true` / `false` - Enable ODE MAP message Deduplication |
+| `ENABLE_ODE_TIM_DEDUPLICATION` | `true` / `false` - Enable ODE TIM message Deduplication |
+| `ENABLE_ODE_RAW_ENCODED_TIM_DEDUPLICATION` | `true` / `false` - Enable ODE Raw Encoded TIM Deduplication |
+| `ENABLE_PROCESSED_SPAT_DEDUPLICATION` | `true` / `false` - Enable ProcessedSpat Deduplication |
+| `ENABLE_ODE_BSM_DEDUPLICATION` | `true` / `false` - Enable ODE BSM Deduplication |
+
+### Generate a Github Token
+
+A GitHub token is required to pull artifacts from GitHub repositories. This is required to obtain the jpo-deduplicator jars and must be done before attempting to build this repository.
+
+1. Log into GitHub.
+2. Navigate to Settings -> Developer settings -> Personal access tokens.
+3. Click "New personal access token (classic)".
+ 1. As of now, GitHub does not support `Fine-grained tokens` for obtaining packages.
+4. Provide a name and expiration for the token.
+5. Select the `read:packages` scope.
+6. Click "Generate token" and copy the token.
+7. Copy the token name and token value into your `.env` file.
+
+For local development the following steps are also required
+8. Create a copy of [settings.xml](jpo-deduplicator/jpo-deduplicator/settings.xml) and save it to `~/.m2/settings.xml`
+9. Update the variables in your `~/.m2/settings.xml` with the token value and target jpo-ode organization.
+
+[Back to top](#table-of-contents)
+
+
+
+## 4. Development Setup
+
+### Integrated Development Environment (IDE)
+
+Install the IDE of your choice:
+
+- Eclipse: [https://eclipse.org/](https://eclipse.org/)
+- STS: [https://spring.io/tools/sts/all](https://spring.io/tools/sts/all)
+- IntelliJ: [https://www.jetbrains.com/idea/](https://www.jetbrains.com/idea/)
+- VS Code: [https://code.visualstudio.com/](https://code.visualstudio.com/)
+
+[Back to top](#table-of-contents)
+
+
+
+## 5. Contact Information
+
+Contact the developers of the JPO-Deduplicator application by submitting a [Github issue](https://github.com/usdot-jpo-ode/jpo-deduplicator/issues).
+
+### License information
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
+file except in compliance with the License.
+
+You may obtain a copy of the License at
+Unless required by applicable law or agreed to in writing, software distributed under
+the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or implied. See the License for the specific language governing
+permissions and limitations under the [License](http://www.apache.org/licenses/LICENSE-2.0).
+
+[Back to top](#table-of-contents)
+
+
+
+## 6. Contributing
+
+Please read the ODE [contributing guide](https://github.com/usdot-jpo-ode/jpo-ode/blob/develop/docs/contributing_guide.md) to learn about our development process, how to propose pull requests and improvements, and how to build and test your changes to this project.
+
+[Back to top](#table-of-contents)
\ No newline at end of file
diff --git a/docker-compose-ode.yml b/docker-compose-ode.yml
new file mode 100644
index 0000000..bebfbca
--- /dev/null
+++ b/docker-compose-ode.yml
@@ -0,0 +1,147 @@
+include:
+ - jpo-utils/docker-compose.yml
+
+services:
+ geojsonconverter:
+ profiles:
+ - all
+ - deduplicator_full
+ - geojsonconverter
+ image: usdotjpoode/geojsonconverter:2025-q1
+ restart: ${RESTART_POLICY}
+ deploy:
+ resources:
+ limits:
+ cpus: '1'
+ memory: 2G
+ environment:
+ DOCKER_HOST_IP: ${DOCKER_HOST_IP:?error}
+ KAFKA_TYPE: ${KAFKA_TYPE}
+ CONFLUENT_KEY: ${CONFLUENT_KEY}
+ CONFLUENT_SECRET: ${CONFLUENT_SECRET}
+ geometry.output.mode: ${GEOMETRY_OUTPUT_MODE:-GEOJSON_ONLY}
+ spring.kafka.bootstrap-servers: ${DOCKER_HOST_IP:?error}:9092
+ logging:
+ options:
+ max-size: "10m"
+ max-file: "5"
+ depends_on:
+ kafka:
+ condition: service_healthy
+ required: false
+ # ODE Services:
+ ode:
+ profiles:
+ - all
+ - deduplicator_full
+ - ode
+ image: usdotjpoode/jpo-ode:2025-q1
+ restart: ${RESTART_POLICY}
+ deploy:
+ resources:
+ limits:
+ cpus: '2'
+ memory: 4G
+ ports:
+ - "8080:8080"
+ - "9090:9090"
+ - "46753:46753/udp"
+ - "46800:46800/udp"
+ - "47900:47900/udp"
+ - "44900:44900/udp"
+ - "44910:44910/udp"
+ - "44920:44920/udp"
+ - "44930:44930/udp"
+ - "44940:44940/udp"
+ - "44990:44990/udp"
+ - "5555:5555/udp"
+ - "6666:6666/udp"
+ environment:
+ DOCKER_HOST_IP: ${DOCKER_HOST_IP:?error}
+ KAFKA_TYPE: ${KAFKA_TYPE}
+ CONFLUENT_KEY: ${CONFLUENT_KEY}
+ CONFLUENT_SECRET: ${CONFLUENT_SECRET}
+ ODE_TIM_INGEST_MONITORING_ENABLED: true
+ ODE_TIM_INGEST_MONITORING_INTERVAL: 60
+ DATA_SIGNING_ENABLED_RSU: false
+ DATA_SIGNING_ENABLED_SDW: false
+ ODE_KAFKA_BROKERS: ${DOCKER_HOST_IP}:9092
+ KAFKA_LINGER_MS: 1
+ KAFKA_BATCH_SIZE: 16384
+ KAFKA_RETRIES: 0
+ depends_on:
+ kafka:
+ condition: service_healthy
+ required: false
+ healthcheck:
+ test: ["CMD", "wget" ,"--spider", "http://localhost:8080"]
+ interval: 5s
+ timeout: 30s
+ retries: 5
+ start_period: 10s
+ logging:
+ options:
+ max-size: "10m"
+ max-file: "5"
+
+ adm:
+ profiles:
+ - all
+ - deduplicator_full
+ - adm
+ image: usdotjpoode/asn1_codec:2025-q1
+ restart: ${RESTART_POLICY}
+ deploy:
+ resources:
+ limits:
+ cpus: '1'
+ memory: 2G
+ environment:
+ DOCKER_HOST_IP: ${DOCKER_HOST_IP:?error}
+ KAFKA_TYPE: ${KAFKA_TYPE}
+ CONFLUENT_KEY: ${CONFLUENT_KEY}
+ CONFLUENT_SECRET: ${CONFLUENT_SECRET}
+ ACM_CONFIG_FILE: adm.properties
+ ACM_LOG_TO_CONSOLE: ${ADM_LOG_TO_CONSOLE:-false}
+ ACM_LOG_TO_FILE: ${ADM_LOG_TO_FILE:-true}
+ ACM_LOG_LEVEL: ${ADM_LOG_LEVEL:-INFO}
+ depends_on:
+ kafka:
+ condition: service_healthy
+ required: false
+ logging:
+ options:
+ max-size: "10m"
+ max-file: "5"
+
+ conflictmonitor:
+ profiles:
+ - all
+ - deduplicator_full
+ - conflictmonitor
+ image: usdotjpoode/jpo-conflictmonitor:2025-q1
+ restart: ${RESTART_POLICY}
+ ports:
+ - "8082:8082"
+ environment:
+ DOCKER_HOST_IP: ${DOCKER_HOST_IP:?error}
+ KAFKA_BOOTSTRAP_SERVERS: ${KAFKA_BOOTSTRAP_SERVERS:?error}
+ kafka.topics.autoCreateTopics: false
+ spring.kafka.bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS:?error}
+ healthcheck:
+ test: ["CMD", "java", "-version"]
+ interval: 10s
+ timeout: 10s
+ retries: 20
+ logging:
+ options:
+ max-size: "10m"
+ max-file: "5"
+ deploy:
+ resources:
+ limits:
+ memory: 3G
+ depends_on:
+ kafka:
+ condition: service_healthy
+ required: false
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..bee6284
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,56 @@
+include:
+ - docker-compose-ode.yml
+services:
+ deduplicator:
+ profiles:
+ - all
+ - deduplicator_base
+ - deduplicator_full
+ build:
+ context: .
+ dockerfile: Dockerfile
+ args:
+ MAVEN_GITHUB_TOKEN: ${MAVEN_GITHUB_TOKEN}
+ MAVEN_GITHUB_ORG: ${MAVEN_GITHUB_ORG}
+ image: jpo-deduplicator:latest
+ privileged: false # Set true to allow writing to /proc/sys/vm/drop_caches
+ restart: ${RESTART_POLICY}
+ ports:
+ - "10091:10090" # JMX
+ environment:
+ DOCKER_HOST_IP: ${DOCKER_HOST_IP}
+ KAFKA_BOOTSTRAP_SERVERS: ${KAFKA_BOOTSTRAP_SERVERS}
+ SPRING_KAFKA_BOOTSTRAPSERVERS: ${KAFKA_BOOTSTRAP_SERVERS}
+ ENABLE_PROCESSED_MAP_DEDUPLICATION: ${ENABLE_PROCESSED_MAP_DEDUPLICATION}
+ ENABLE_PROCESSED_MAP_WKT_DEDUPLICATION: ${ENABLE_PROCESSED_MAP_WKT_DEDUPLICATION}
+ ENABLE_ODE_MAP_DEDUPLICATION: ${ENABLE_ODE_MAP_DEDUPLICATION}
+ ENABLE_ODE_TIM_DEDUPLICATION: ${ENABLE_ODE_TIM_DEDUPLICATION}
+ ENABLE_ODE_RAW_ENCODED_TIM_DEDUPLICATION: ${ENABLE_ODE_RAW_ENCODED_TIM_DEDUPLICATION}
+ ENABLE_PROCESSED_SPAT_DEDUPLICATION: ${ENABLE_PROCESSED_SPAT_DEDUPLICATION}
+ ENABLE_ODE_BSM_DEDUPLICATION: ${ENABLE_ODE_BSM_DEDUPLICATION}
+ DEDUPLICATOR_ROCKSDB_TOTAL_OFF_HEAP_MEMORY: ${DEDUPLICATOR_ROCKSDB_TOTAL_OFF_HEAP_MEMORY}
+ DEDUPLICATOR_ROCKSDB_INDEX_FILTER_BLOCK_RATIO: ${DEDUPLICATOR_ROCKSDB_INDEX_FILTER_BLOCK_RATIO}
+ DEDUPLICATOR_ROCKSDB_TOTAL_MEMTABLE_MEMORY: ${DEDUPLICATOR_ROCKSDB_TOTAL_MEMTABLE_MEMORY}
+ DEDUPLICATOR_ROCKSDB_BLOCK_SIZE: ${DEDUPLICATOR_ROCKSDB_BLOCK_SIZE}
+ DEDUPLICATOR_ROCKSDB_N_MEMTABLES: ${DEDUPLICATOR_ROCKSDB_N_MEMTABLES}
+ DEDUPLICATOR_ROCKSDB_MEMTABLE_SIZE: ${DEDUPLICATOR_ROCKSDB_MEMTABLE_SIZE}
+ KAFKA_TYPE: ${KAFKA_TYPE}
+ CONFLUENT_KEY: ${CONFLUENT_KEY}
+ CONFLUENT_SECRET: ${CONFLUENT_SECRET}
+ healthcheck:
+ test: ["CMD", "java", "-version"]
+ interval: 10s
+ timeout: 10s
+ retries: 20
+ logging:
+ options:
+ max-size: "10m"
+ max-file: "5"
+ deploy:
+ resources:
+ limits:
+ memory: 1G
+ depends_on:
+ kafka:
+ condition: service_healthy
+ required: false
\ No newline at end of file
diff --git a/docs/Release_notes.md b/docs/Release_notes.md
new file mode 100644
index 0000000..34fb1a5
--- /dev/null
+++ b/docs/Release_notes.md
@@ -0,0 +1,17 @@
+JPO-Deduplicator Release Notes
+Version 2.0.0
+Summary
+The first release of the jpo-deduplicator package. This package focuses on removing duplicate messages from Kafka topics. This in turns saves deployers costs associated with data transfer and storage within the ODE ecosystem. This initial release included deduplication for the following messages types
+ - ProcessedMap
+ - ProcessedMapWKT
+ - ProcessedSpat
+ - OdeMapJson
+ - OdeBSMJson
+ - OdeTIMJson
+ - OdeRawEncodedTIm
+
+This release also makes additional changes to the submodule components as follows
+
+Refactored docker-compose files to use compose profiles for modular component approach
+Updated jpo-deduplicator for compatibility with jpo-ode version 4.0.0
+Updated jpo-deduplicator to use zstd compression for output messages
\ No newline at end of file
diff --git a/jpo-deduplicator/LICENSE-2.0.html b/jpo-deduplicator/LICENSE-2.0.html
new file mode 100644
index 0000000..d1055c8
--- /dev/null
+++ b/jpo-deduplicator/LICENSE-2.0.html
@@ -0,0 +1,228 @@
+
+
+
+
+
+ Apache License, Version 2.0
+
+
+
+
+
Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND
+ DISTRIBUTION
+
1.
+ Definitions .
+
"License" shall mean the terms and conditions for use,
+ reproduction, and distribution as defined by Sections 1 through 9
+ of this document.
+
"Licensor" shall mean the copyright owner or entity authorized
+ by the copyright owner that is granting the License.
+
"Legal Entity" shall mean the union of the acting entity and
+ all other entities that control, are controlled by, or are under
+ common control with that entity. For the purposes of this
+ definition, "control" means (i) the power, direct or indirect, to
+ cause the direction or management of such entity, whether by
+ contract or otherwise, or (ii) ownership of fifty percent (50%)
+ or more of the outstanding shares, or (iii) beneficial ownership
+ of such entity.
+
"You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
"Source" form shall mean the preferred form for making
+ modifications, including but not limited to software source code,
+ documentation source, and configuration files.
+
"Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but not
+ limited to compiled object code, generated documentation, and
+ conversions to other media types.
+
"Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work (an
+ example is provided in the Appendix below).
+
"Derivative Works" shall mean any work, whether in Source or
+ Object form, that is based on (or derived from) the Work and for
+ which the editorial revisions, annotations, elaborations, or
+ other modifications represent, as a whole, an original work of
+ authorship. For the purposes of this License, Derivative Works
+ shall not include works that remain separable from, or merely
+ link (or bind by name) to the interfaces of, the Work and
+ Derivative Works thereof.
+
"Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or
+ additions to that Work or Derivative Works thereof, that is
+ intentionally submitted to Licensor for inclusion in the Work by
+ the copyright owner or by an individual or Legal Entity
+ authorized to submit on behalf of the copyright owner. For the
+ purposes of this definition, "submitted" means any form of
+ electronic, verbal, or written communication sent to the Licensor
+ or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control
+ systems, and issue tracking systems that are managed by, or on
+ behalf of, the Licensor for the purpose of discussing and
+ improving the Work, but excluding communication that is
+ conspicuously marked or otherwise designated in writing by the
+ copyright owner as "Not a Contribution."
+
"Contributor" shall mean Licensor and any individual or Legal
+ Entity on behalf of whom a Contribution has been received by
+ Licensor and subsequently incorporated within the Work.
+
2. Grant of
+ Copyright License . Subject to the terms and
+ conditions of this License, each Contributor hereby grants to You
+ a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
+ irrevocable copyright license to reproduce, prepare Derivative
+ Works of, publicly display, publicly perform, sublicense, and
+ distribute the Work and such Derivative Works in Source or Object
+ form.
+
3. Grant of Patent
+ License . Subject to the terms and conditions of this
+ License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have
+ made, use, offer to sell, sell, import, and otherwise transfer
+ the Work, where such license applies only to those patent claims
+ licensable by such Contributor that are necessarily infringed by
+ their Contribution(s) alone or by combination of their
+ Contribution(s) with the Work to which such Contribution(s) was
+ submitted. If You institute patent litigation against any entity
+ (including a cross-claim or counterclaim in a lawsuit) alleging
+ that the Work or a Contribution incorporated within the Work
+ constitutes direct or contributory patent infringement, then any
+ patent licenses granted to You under this License for that Work
+ shall terminate as of the date such litigation is filed.
+
4.
+ Redistribution . You may reproduce and distribute
+ copies of the Work or Derivative Works thereof in any medium,
+ with or without modifications, and in Source or Object form,
+ provided that You meet the following conditions:
+
+ You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+ You must cause any modified files to carry prominent
+ notices stating that You changed the files; and
+ You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work, excluding
+ those notices that do not pertain to any part of the Derivative
+ Works; and
+ If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute
+ must include a readable copy of the attribution notices
+ contained within such NOTICE file, excluding those notices that
+ do not pertain to any part of the Derivative Works, in at least
+ one of the following places: within a NOTICE text file
+ distributed as part of the Derivative Works; within the Source
+ form or documentation, if provided along with the Derivative
+ Works; or, within a display generated by the Derivative Works,
+ if and wherever such third-party notices normally appear. The
+ contents of the NOTICE file are for informational purposes only
+ and do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed as
+ modifying the License.
+
+ You may add Your own copyright statement to Your modifications
+ and may provide additional or different license terms and
+ conditions for use, reproduction, or distribution of Your
+ modifications, or for any such Derivative Works as a whole,
+ provided Your use, reproduction, and distribution of the Work
+ otherwise complies with the conditions stated in this
+ License.
+
+
5.
+ Submission of Contributions . Unless You explicitly
+ state otherwise, any Contribution intentionally submitted for
+ inclusion in the Work by You to the Licensor shall be under the
+ terms and conditions of this License, without any additional
+ terms or conditions. Notwithstanding the above, nothing herein
+ shall supersede or modify the terms of any separate license
+ agreement you may have executed with Licensor regarding such
+ Contributions.
+
6.
+ Trademarks . This License does not grant permission
+ to use the trade names, trademarks, service marks, or product
+ names of the Licensor, except as required for reasonable and
+ customary use in describing the origin of the Work and
+ reproducing the content of the NOTICE file.
+
7. Disclaimer
+ of Warranty . Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or
+ conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or
+ FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
+ determining the appropriateness of using or redistributing the
+ Work and assume any risks associated with Your exercise of
+ permissions under this License.
+
8. Limitation
+ of Liability . In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect,
+ special, incidental, or consequential damages of any character
+ arising as a result of this License or out of the use or
+ inability to use the Work (including but not limited to damages
+ for loss of goodwill, work stoppage, computer failure or
+ malfunction, or any and all other commercial damages or losses),
+ even if such Contributor has been advised of the possibility of
+ such damages.
+
9. Accepting
+ Warranty or Additional Liability . While
+ redistributing the Work or Derivative Works thereof, You may
+ choose to offer, and charge a fee for, acceptance of support,
+ warranty, indemnity, or other liability obligations and/or rights
+ consistent with this License. However, in accepting such
+ obligations, You may act only on Your own behalf and on Your sole
+ responsibility, not on behalf of any other Contributor, and only
+ if You agree to indemnify, defend, and hold each Contributor
+ harmless for any liability incurred by, or claims asserted
+ against, such Contributor by reason of your accepting any such
+ warranty or additional liability.
+
END OF TERMS AND CONDITIONS
+
APPENDIX: How to apply the Apache License to your
+ work
+
To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a file
+ or class name and description of purpose be included on the same
+ "printed page" as the copyright notice for easier identification
+ within third-party archives.
+
+
Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+
+
+
+
+
diff --git a/jpo-deduplicator/pom.xml b/jpo-deduplicator/pom.xml
new file mode 100644
index 0000000..47ff3df
--- /dev/null
+++ b/jpo-deduplicator/pom.xml
@@ -0,0 +1,336 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.1.3
+
+
+ usdot.jpo.ode
+ jpo-deduplicator
+ 2.0.0
+ jar
+ jpo-deduplicator
+ http://maven.apache.org
+
+ UTF-8
+ 29-SNAPSHOT
+ usdot-jpo-ode
+ https://sonarcloud.io
+
+ Deduplicates Messages generated by Subcomponents of the ODE
+ 21
+
+ ^
+
+
+ 0.8.11
+ jacoco
+ reuseReports
+ ${project.basedir}/target/site/jacoco/jacoco.xml
+ java
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.apache.logging.log4j
+ log4j-to-slf4j
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ com.vaadin.external.google
+ android-json
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-data-rest
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.restdocs
+ spring-restdocs-mockmvc
+ test
+
+
+ org.springframework.boot
+ spring-boot-configuration-processor
+ true
+
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
+
+ org.springframework.kafka
+ spring-kafka
+
+
+ org.springframework.kafka
+ spring-kafka-test
+ test
+
+
+
+
+ usdot.jpo.ode
+ jpo-ode-core
+ 4.0.0
+
+
+ usdot.jpo.ode
+ jpo-ode-plugins
+ 4.0.0
+
+
+ usdot.jpo.ode
+ jpo-geojsonconverter
+ 2.0.0
+
+
+ usdot.jpo.ode
+ jpo-conflictmonitor
+ 1.5.0
+
+
+ junit
+ junit
+ 4.13.2
+ test
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+ test
+
+
+ org.mockito
+ mockito-core
+ 5.10.0
+ test
+
+
+
+ com.google.guava
+ guava
+ 33.0.0-jre
+
+
+
+
+
+
+
+ org.projectlombok
+ lombok
+ 1.18.30
+
+
+
+
+
+
+
+
+ false
+
+ central
+ Central Repository
+ https://repo.maven.apache.org/maven2
+
+
+
+
+
+ ${project.artifactId}
+
+
+ org.sonarsource.scanner.maven
+ sonar-maven-plugin
+ 3.10.0.2594
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ build-info
+
+ build-info
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 3.2.5
+
+ all
+ exit
+
+
+
+ @{argLine}
+ -XX:+EnableDynamicAgentLoading
+
+
+
+
+
+ org.apache.maven.surefire
+ surefire-junit47
+ 3.2.5
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ jacoco-initialize
+
+ prepare-agent
+
+
+
+ jacoco-site
+ package
+
+ report
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.3.0
+
+
+
+ jar
+
+ package
+
+
+ jpo-deduplicator
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-report-plugin
+ 3.2.5
+
+
+
+
+
+ package-jar
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.0
+
+
+
+ true
+ lib/
+
+ us.dot.its.jpo.deduplicator.DeduplicatorApplication
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ repackage
+ none
+
+
+
+
+
+
+
+
+
+
+ github
+ GitHub Packages
+ https://maven.pkg.github.com/${github_organization}/jpo-deduplicator
+
+
+
diff --git a/jpo-deduplicator/settings.xml b/jpo-deduplicator/settings.xml
new file mode 100644
index 0000000..2a4f90b
--- /dev/null
+++ b/jpo-deduplicator/settings.xml
@@ -0,0 +1,28 @@
+
+
+
+ default
+
+
+
+ github
+ jpo_deduplicator
+ ${env.MAVEN_GITHUB_TOKEN}
+
+
+
+
+ default
+
+
+ github
+ GitHub JPO Conflict Monitor
+ https://maven.pkg.github.com/${env.MAVEN_GITHUB_ORG}/*
+
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorApplication.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorApplication.java
new file mode 100644
index 0000000..6b483c9
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorApplication.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2018 572682
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package us.dot.its.jpo.deduplicator;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+
+@SpringBootApplication
+@EnableConfigurationProperties(DeduplicatorProperties.class)
+public class DeduplicatorApplication {
+
+ private static final Logger logger = LoggerFactory.getLogger(DeduplicatorApplication.class);
+
+ static final int DEFAULT_NO_THREADS = 10;
+ static final String DEFAULT_SCHEMA = "default";
+
+ public static void main(String[] args) throws MalformedObjectNameException, InterruptedException,
+ InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
+
+ logger.info("Starting Message Deduplicator");
+ SpringApplication.run(DeduplicatorApplication.class, args);
+ // MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ // SystemConfig mBean = new SystemConfig(DEFAULT_NO_THREADS, DEFAULT_SCHEMA);
+ // ObjectName name = new ObjectName("us.dot.its.jpo.geojson:type=SystemConfig");
+ // mbs.registerMBean(mBean, name);
+ logger.info("Message Deduplicator has started");
+
+ }
+
+ @Bean
+ CommandLineRunner init(DeduplicatorProperties geojsonProperties) {
+ return args -> {
+ };
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorProperties.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorProperties.java
new file mode 100644
index 0000000..8f90068
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/DeduplicatorProperties.java
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * Copyright 2018 572682
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ ******************************************************************************/
+package us.dot.its.jpo.deduplicator;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Properties;
+import java.util.UUID;
+
+import jakarta.annotation.PostConstruct;
+
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.kafka.clients.producer.ProducerConfig;
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.StreamsConfig;
+import org.apache.kafka.streams.errors.LogAndContinueExceptionHandler;
+import org.apache.kafka.streams.processor.LogAndSkipOnInvalidTimestamp;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.info.BuildProperties;
+import org.springframework.context.EnvironmentAware;
+import org.springframework.core.env.Environment;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.AccessLevel;
+import us.dot.its.jpo.conflictmonitor.AlwaysContinueProductionExceptionHandler;
+import us.dot.its.jpo.deduplicator.deduplicator.BoundedMemoryRocksDBConfig;
+import us.dot.its.jpo.ode.eventlog.EventLogger;
+import us.dot.its.jpo.ode.util.CommonUtils;
+
+// import us.dot.its.jpo.conflictmonitor.AlwaysContinueProductionExceptionHandler;
+
+@Getter
+@Setter
+@ConfigurationProperties
+public class DeduplicatorProperties implements EnvironmentAware {
+
+ private static final Logger logger = LoggerFactory.getLogger(DeduplicatorProperties.class);
+
+ // Processed Map Configuration
+ private String kafkaTopicProcessedMap;
+ private String kafkaTopicDeduplicatedProcessedMap;
+ private boolean enableProcessedMapDeduplication;
+ private String kafkaStateStoreProcessedMapName = "ProcessedMap-store";
+
+ // Processed Map WKT Configuration
+ private String kafkaTopicProcessedMapWKT;
+ private String kafkaTopicDeduplicatedProcessedMapWKT;
+ private boolean enableProcessedMapWktDeduplication;
+ private String kafkaStateStoreProcessedMapWKTName = "ProcessedMapWKT-store";
+
+ // Ode Map Json Configuration
+ private String kafkaTopicOdeMapJson;
+ private String kafkaTopicDeduplicatedOdeMapJson;
+ private boolean enableOdeMapDeduplication;
+ private String kafkaStateStoreOdeMapJsonName = "OdeMapJson-store";
+
+ // Ode Tim Json Configuration
+ private String kafkaTopicOdeTimJson;
+ private String kafkaTopicDeduplicatedOdeTimJson;
+ private boolean enableOdeTimDeduplication;
+ private String kafkaStateStoreOdeTimJsonName = "OdeTimJson-store";
+
+ // Ode Raw Encoded Tim Json Configuration
+ private String kafkaTopicOdeRawEncodedTimJson;
+ private String kafkaTopicDeduplicatedOdeRawEncodedTimJson;
+ private boolean enableOdeRawEncodedTimDeduplication;
+ private String kafkaStateStoreOdeRawEncodedTimJsonName = "OdeRawEncodedTimJson-store";
+
+ //Ode BsmJson Configuration
+ private String kafkaTopicOdeBsmJson;
+ private String kafkaTopicDeduplicatedOdeBsmJson;
+ private boolean enableOdeBsmDeduplication;
+ private long odeBsmMaximumTimeDelta;
+ private double odeBsmMaximumPositionDelta;
+ private double odeBsmAlwaysIncludeAtSpeed;
+ private String kafkaStateStoreOdeBsmJsonName = "OdeBsmJson-store";
+
+ // Confluent Properties
+ private boolean confluentCloudEnabled = false;
+ private String confluentKey = null;
+ private String confluentSecret = null;
+
+ // Processed SPaT Configuration
+ private String kafkaTopicProcessedSpat;
+ private String kafkaTopicDeduplicatedProcessedSpat;
+ private boolean enableProcessedSpatDeduplication;
+ private String kafkaStateStoreProcessedSpatName = "ProcessedSpat-store";
+
+
+ private int lingerMs = 0;
+
+
+
+ @Autowired
+ @Setter(AccessLevel.NONE)
+ private Environment env;
+
+ /*
+ * General Properties
+ */
+ private String version;
+ // public static final int OUTPUT_SCHEMA_VERSION = 6;
+
+ @Setter(AccessLevel.NONE)
+ private String kafkaBrokers = null;
+
+ private static final String DEFAULT_KAFKA_PORT = "9092";
+ private static final String DEFAULT_CONNECT_PORT = "8083";
+
+ @Setter(AccessLevel.NONE)
+ private String hostId;
+
+ // @Setter(AccessLevel.NONE)
+ // private String connectURL = null;
+
+ // @Setter(AccessLevel.NONE)
+ // private String dockerHostIP = null;
+
+ @Setter(AccessLevel.NONE)
+ private String kafkaBrokerIP = null;
+
+
+ // @Setter(AccessLevel.NONE)
+ // private String dbHostIP = null;
+
+
+ @Setter(AccessLevel.NONE)
+ @Autowired
+ BuildProperties buildProperties;
+
+ @PostConstruct
+ void initialize() {
+ setVersion(buildProperties.getVersion());
+ logger.info("groupId: {}", buildProperties.getGroup());
+ logger.info("artifactId: {}", buildProperties.getArtifact());
+ logger.info("version: {}", version);
+ //OdeMsgMetadata.setStaticSchemaVersion(OUTPUT_SCHEMA_VERSION);
+
+
+
+ String hostname;
+ try {
+ hostname = InetAddress.getLocalHost().getHostName();
+ } catch (UnknownHostException e) {
+ // Let's just use a random hostname
+ hostname = UUID.randomUUID().toString();
+ logger.info("Unknown host error: {}, using random", e);
+ }
+ hostId = hostname;
+ logger.info("Host ID: {}", hostId);
+ EventLogger.logger.info("Initializing services on host {}", hostId);
+
+ // if(dbHostIP == null){
+ // String dbHost = CommonUtils.getEnvironmentVariable("MONGO_IP");
+
+ // if(dbHost == null){
+ // logger.warn(
+ // "DB Host IP not defined, Defaulting to localhost.");
+ // dbHost = "localhost";
+ // }
+ // dbHostIP = dbHost;
+ // }
+
+ if (kafkaBrokers == null) {
+
+ String kafkaBrokers = CommonUtils.getEnvironmentVariable("KAFKA_BOOTSTRAP_SERVERS");
+
+ logger.info("ode.kafkaBrokers property not defined. Will try KAFKA_BOOTSTRAP_SERVERS => {}", kafkaBrokers);
+
+ if (kafkaBrokers == null) {
+ logger.warn(
+ "Neither ode.kafkaBrokers ode property nor KAFKA_BOOTSTRAP_SERVERS environment variable are defined. Defaulting to localhost:9092");
+ kafkaBrokers = "localhost:9092";
+ }
+
+ }
+
+ String kafkaType = CommonUtils.getEnvironmentVariable("KAFKA_TYPE");
+ if (kafkaType != null) {
+ confluentCloudEnabled = kafkaType.equals("CONFLUENT");
+ if (confluentCloudEnabled) {
+
+ logger.info("Enabling Confluent Cloud Integration");
+
+ confluentKey = CommonUtils.getEnvironmentVariable("CONFLUENT_KEY");
+ confluentSecret = CommonUtils.getEnvironmentVariable("CONFLUENT_SECRET");
+ }
+ }
+
+ // Initialize the Kafka Connect URL
+ // if (connectURL == null) {
+ // String connectURL = CommonUtils.getEnvironmentVariable("CONNECT_URL");
+ // if (connectURL == null) {
+ // connectURL = String.format("http://%s:%s", "localhost", DEFAULT_CONNECT_PORT);
+ // }
+ // }
+
+ // List asList = Arrays.asList(this.getKafkaTopicsDisabled());
+ // logger.info("Disabled Topics: {}", asList);
+ // kafkaTopicsDisabledSet.addAll(asList);
+ }
+
+ public Properties createStreamProperties(String name) {
+ Properties streamProps = new Properties();
+ streamProps.put(StreamsConfig.APPLICATION_ID_CONFIG, name);
+
+ streamProps.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, kafkaBrokers);
+
+ streamProps.put(StreamsConfig.DEFAULT_DESERIALIZATION_EXCEPTION_HANDLER_CLASS_CONFIG,
+ LogAndContinueExceptionHandler.class.getName());
+
+ streamProps.put(StreamsConfig.DEFAULT_TIMESTAMP_EXTRACTOR_CLASS_CONFIG,
+ LogAndSkipOnInvalidTimestamp.class.getName());
+
+ streamProps.put(StreamsConfig.DEFAULT_PRODUCTION_EXCEPTION_HANDLER_CLASS_CONFIG,
+ AlwaysContinueProductionExceptionHandler.class.getName());
+
+ streamProps.put(StreamsConfig.NUM_STREAM_THREADS_CONFIG, 2);
+
+ // streamProps.put(StreamsConfig.producerPrefix("acks"), "all");
+ streamProps.put(StreamsConfig.producerPrefix(ProducerConfig.ACKS_CONFIG), "all");
+
+ // Reduce cache buffering per topology to 1MB
+ streamProps.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 1 * 1024 * 1024L);
+ // Optionally, to disable caching:
+ //streamProps.put(StreamsConfig.STATESTORE_CACHE_MAX_BYTES_CONFIG, 0);
+
+
+ // Decrease default commit interval. Default for 'at least once' mode of 30000ms
+ // is too slow.
+ streamProps.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 100);
+
+ // All the keys are Strings in this app
+ streamProps.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
+
+ // Configure the state store location
+ if (SystemUtils.IS_OS_LINUX) {
+ streamProps.put(StreamsConfig.STATE_DIR_CONFIG, "/var/lib/ode/kafka-streams");
+ } else if (SystemUtils.IS_OS_WINDOWS) {
+ streamProps.put(StreamsConfig.STATE_DIR_CONFIG, "C:/temp/ode");
+ }
+ // streamProps.put(StreamsConfig.STATE_DIR_CONFIG, "/var/lib/")\
+
+ // Increase max.block.ms and delivery.timeout.ms for streams
+ final int FIVE_MINUTES_MS = 5 * 60 * 1000;
+ streamProps.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, FIVE_MINUTES_MS);
+ streamProps.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, FIVE_MINUTES_MS);
+
+ // Disable batching
+ // streamProps.put(ProducerConfig.BATCH_SIZE_CONFIG, 0);
+
+ streamProps.put(ProducerConfig.COMPRESSION_TYPE_CONFIG, "zstd");
+ streamProps.put(ProducerConfig.LINGER_MS_CONFIG, getKafkaLingerMs());
+
+ if (confluentCloudEnabled) {
+ streamProps.put("ssl.endpoint.identification.algorithm", "https");
+ streamProps.put("security.protocol", "SASL_SSL");
+ streamProps.put("sasl.mechanism", "PLAIN");
+
+ if (confluentKey != null && confluentSecret != null) {
+ String auth = "org.apache.kafka.common.security.plain.PlainLoginModule required " +
+ "username=\"" + confluentKey + "\" " +
+ "password=\"" + confluentSecret + "\";";
+ streamProps.put("sasl.jaas.config", auth);
+ }
+ else {
+ logger.error("Environment variables CONFLUENT_KEY and CONFLUENT_SECRET are not set. Set these in the .env file to use Confluent Cloud");
+ }
+ }
+
+ // Configure RocksDB memory usage
+ streamProps.put(StreamsConfig.ROCKSDB_CONFIG_SETTER_CLASS_CONFIG, BoundedMemoryRocksDBConfig.class);
+
+ return streamProps;
+ }
+
+ public String getProperty(String key) {
+ return env.getProperty(key);
+ }
+
+ public String getProperty(String key, String defaultValue) {
+ return env.getProperty(key, defaultValue);
+ }
+
+ public Object getProperty(String key, int i) {
+ return env.getProperty(key, Integer.class, i);
+ }
+
+ public Boolean getConfluentCloudStatus() {
+ return confluentCloudEnabled;
+ }
+
+
+ @Value("${kafkaTopicProcessedMap}")
+ public void setKafkaTopicProcessedMap(String kafkaTopicProcessedMap) {
+ this.kafkaTopicProcessedMap = kafkaTopicProcessedMap;
+ }
+
+ @Value("${kafkaTopicDeduplicatedProcessedMap}")
+ public void setKafkaTopicDeduplicatedProcessedMap(String kafkaTopicDeduplicatedProcessedMap) {
+ this.kafkaTopicDeduplicatedProcessedMap = kafkaTopicDeduplicatedProcessedMap;
+ }
+
+ @Value("${enableProcessedMapDeduplication}")
+ public void setEnableProcessedMapDeduplication(boolean enableProcessedMapDeduplication) {
+ this.enableProcessedMapDeduplication = enableProcessedMapDeduplication;
+ }
+
+ @Value("${kafkaTopicProcessedMapWKT}")
+ public void setKafkaTopicProcessedMapWKT(String kafkaTopicProcessedMapWKT) {
+ this.kafkaTopicProcessedMapWKT = kafkaTopicProcessedMapWKT;
+ }
+
+ @Value("${kafkaTopicDeduplicatedProcessedMapWKT}")
+ public void setKafkaTopicDeduplicatedProcessedMapWKT(String kafkaTopicDeduplicatedProcessedMapWKT) {
+ this.kafkaTopicDeduplicatedProcessedMapWKT = kafkaTopicDeduplicatedProcessedMapWKT;
+ }
+
+ @Value("${enableProcessedMapWktDeduplication}")
+ public void setEnableProcessedMapWktDeduplication(boolean enableProcessedMapWktDeduplication) {
+ this.enableProcessedMapWktDeduplication = enableProcessedMapWktDeduplication;
+ }
+
+ @Value("${kafkaTopicOdeMapJson}")
+ public void setKafkaTopicOdeMapJson(String kafkaTopicOdeMapJson) {
+ this.kafkaTopicOdeMapJson = kafkaTopicOdeMapJson;
+ }
+
+ @Value("${kafkaTopicDeduplicatedOdeMapJson}")
+ public void setKafkaTopicDeduplicatedOdeMapJson(String kafkaTopicDeduplicatedOdeMapJson) {
+ this.kafkaTopicDeduplicatedOdeMapJson = kafkaTopicDeduplicatedOdeMapJson;
+ }
+
+ @Value("${enableOdeMapDeduplication}")
+ public void setEnableOdeMapDeduplication(boolean enableOdeMapDeduplication) {
+ this.enableOdeMapDeduplication = enableOdeMapDeduplication;
+ }
+
+ @Value("${kafkaTopicOdeTimJson}")
+ public void setKafkaTopicOdeTimJson(String kafkaTopicOdeTimJson) {
+ this.kafkaTopicOdeTimJson = kafkaTopicOdeTimJson;
+ }
+
+ @Value("${kafkaTopicDeduplicatedOdeTimJson}")
+ public void setKafkaTopicDeduplicatedOdeTimJson(String kafkaTopicDeduplicatedOdeTimJson) {
+ this.kafkaTopicDeduplicatedOdeTimJson = kafkaTopicDeduplicatedOdeTimJson;
+ }
+
+ @Value("${enableOdeTimDeduplication}")
+ public void setEnableOdeTimDeduplication(boolean enableOdeTimDeduplication) {
+ this.enableOdeTimDeduplication = enableOdeTimDeduplication;
+ }
+
+ @Value("${kafkaTopicOdeRawEncodedTimJson}")
+ public void setKafkaTopicOdeRawEncodedTimJson(String kafkaTopicOdeRawEncodedTimJson) {
+ this.kafkaTopicOdeRawEncodedTimJson = kafkaTopicOdeRawEncodedTimJson;
+ }
+
+ @Value("${kafkaTopicDeduplicatedOdeRawEncodedTimJson}")
+ public void setKafkaTopicDeduplicatedOdeRawEncodedTimJson(String kafkaTopicDeduplicatedOdeRawEncodedTimJson) {
+ this.kafkaTopicDeduplicatedOdeRawEncodedTimJson = kafkaTopicDeduplicatedOdeRawEncodedTimJson;
+ }
+
+ @Value("${enableOdeRawEncodedTimDeduplication}")
+ public void setEnableOdeRawEncodedTimDeduplication(boolean enableOdeRawEncodedTimDeduplication) {
+ this.enableOdeRawEncodedTimDeduplication = enableOdeRawEncodedTimDeduplication;
+ }
+
+ @Value("${kafkaTopicOdeBsmJson}")
+ public void setkafkaTopicOdeBsmJson(String kafkaTopicOdeBsmJson) {
+ this.kafkaTopicOdeBsmJson = kafkaTopicOdeBsmJson;
+ }
+
+ @Value("${kafkaTopicDeduplicatedOdeBsmJson}")
+ public void setkafkaTopicDeduplicatedOdeBsmJson(String kafkaTopicDeduplicatedOdeBsmJson) {
+ this.kafkaTopicDeduplicatedOdeBsmJson = kafkaTopicDeduplicatedOdeBsmJson;
+ }
+
+ @Value("${enableOdeBsmDeduplication}")
+ public void setenableOdeBsmDeduplication(boolean enableOdeBsmDeduplication) {
+ this.enableOdeBsmDeduplication = enableOdeBsmDeduplication;
+ }
+
+ @Value("${odeBsmMaximumTimeDelta}")
+ public void setMaximumTimeDelta(long maximumTimeDelta) {
+ this.odeBsmMaximumTimeDelta = maximumTimeDelta;
+ }
+
+ @Value("${odeBsmMaximumPositionDelta}")
+ public void setMaximumPositionDelta(double maximumPositionDelta) {
+ this.odeBsmMaximumPositionDelta = maximumPositionDelta;
+ }
+
+ @Value("${odeBsmAlwaysIncludeAtSpeed}")
+ public void setAlwaysIncludeAtSpeed(double alwaysIncludeAtSpeed) {
+ this.odeBsmAlwaysIncludeAtSpeed = alwaysIncludeAtSpeed;
+ }
+
+ @Value("${spring.kafka.bootstrap-servers}")
+ public void setKafkaBrokers(String kafkaBrokers) {
+ this.kafkaBrokers = kafkaBrokers;
+ }
+
+ @Value("${kafkaTopicProcessedSpat}")
+ public void setKafkaTopicProcessedSpat(String kafkaTopicProcessedSpat) {
+ this.kafkaTopicProcessedSpat = kafkaTopicProcessedSpat;
+ }
+
+ @Value("${kafkaTopicDeduplicatedProcessedSpat}")
+ public void setKafkaTopicDeduplicatedProcessedSpat(String kafkaTopicDeduplicatedProcessedSpat) {
+ this.kafkaTopicDeduplicatedProcessedSpat = kafkaTopicDeduplicatedProcessedSpat;
+ }
+
+ @Value("${enableProcessedSpatDeduplication}")
+ public void setEnableProcessedSpatDeduplication(boolean enableProcessedSpatDeduplication) {
+ this.enableProcessedSpatDeduplication = enableProcessedSpatDeduplication;
+ }
+
+ @Override
+ public void setEnvironment(Environment environment) {
+ env = environment;
+ }
+
+ @Value("${kafka.linger_ms}")
+ public void setKafkaLingerMs(int lingerMs) {
+ this.lingerMs = lingerMs;
+ }
+
+ public int getKafkaLingerMs() {
+ return lingerMs;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/KafkaConfiguration.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/KafkaConfiguration.java
new file mode 100644
index 0000000..a5cac5f
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/KafkaConfiguration.java
@@ -0,0 +1,197 @@
+package us.dot.its.jpo.deduplicator;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import org.apache.kafka.clients.admin.NewTopic;
+import org.apache.kafka.common.serialization.StringSerializer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.kafka.config.TopicBuilder;
+import org.springframework.kafka.core.DefaultKafkaProducerFactory;
+import org.springframework.kafka.core.KafkaAdmin;
+import org.springframework.kafka.core.KafkaAdmin.NewTopics;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.kafka.core.ProducerFactory;
+import org.springframework.stereotype.Component;
+import org.apache.kafka.clients.producer.ProducerConfig;
+
+@Component
+@ConfigurationProperties(prefix = "kafka.topics")
+public class KafkaConfiguration {
+
+ @Autowired
+ private DeduplicatorProperties properties;
+
+ @Bean(name = "createKafkaTopics")
+ public KafkaAdmin.NewTopics createKafkaTopics() {
+ logger.info("createTopic");
+ List newTopics = new ArrayList<>();
+
+ if(!properties.getConfluentCloudStatus()){
+ try {
+ for(var propEntry : admin.getConfigurationProperties().entrySet()) {
+ logger.info("KafkaAdmin property {} = {}", propEntry.getKey(), propEntry.getValue());
+ }
+
+ if (!autoCreateTopics) {
+ logger.info("Auto create topics is disabled");
+ return null;
+ }
+
+ logger.info("Creating topics: {}", createTopics);
+
+
+
+ List topicNames = new ArrayList<>();
+ for (var topic : createTopics) {
+
+ // Get the name and config settings for the topic
+ String topicName = (String)topic.getOrDefault("name", null);
+ if (topicName == null) {
+ logger.error("CreateTopic {} has no topic name", topic);
+ break;
+ }
+ topicNames.add(topicName);
+
+ Map topicConfigs = new HashMap<>();
+ String cleanupPolicy = (String)topic.getOrDefault("cleanupPolicy", null);
+ if (cleanupPolicy != null) {
+ topicConfigs.put("cleanup.policy", cleanupPolicy);
+ }
+ Integer retentionMs = (Integer)topic.getOrDefault("retentionMs", null);
+ if (retentionMs != null) {
+ topicConfigs.put("retention.ms", retentionMs.toString());
+ }
+
+ NewTopic newTopic = TopicBuilder
+ .name(topicName)
+ .partitions(numPartitions)
+ .replicas(numReplicas)
+ .configs(topicConfigs)
+ .build();
+ newTopics.add(newTopic);
+ logger.info("New Topic: {}", newTopic);
+ }
+
+ // Explicitly create the topics here to prevent error on first run
+ admin.initialize();
+ admin.createOrModifyTopics(newTopics.toArray(new NewTopic[0]));
+
+ // Check that topics were created
+ var topicDescMap = admin.describeTopics(topicNames.toArray(new String[0]));
+ for (var entry : topicDescMap.entrySet()) {
+ String topicName = entry.getKey();
+ var desc = entry.getValue();
+ logger.info("Created topic {}: {}", topicName, desc);
+ }
+
+
+ } catch (Exception e) {
+ logger.error("Exception in createKafkaTopics", e);
+ throw e;
+ }
+ }
+
+ // List out existing topics
+ // Admin adminClient = Admin.create(properties.createStreamProperties("DeduplicatorAdminClient"));
+ // ListTopicsOptions listTopicsOptions = new ListTopicsOptions().listInternal(true);
+ // ListTopicsResult topicsResult = adminClient.listTopics(listTopicsOptions);
+ // KafkaFuture> topicsFuture = topicsResult.names();
+ // try {
+ // List topicNames = new ArrayList<>();
+ // for(String topicName: topicsFuture.get()){
+ // logger.info("Found Topic: " + topicName);
+ // topicNames.add(topicName);
+ // }
+
+ // } catch (InterruptedException e) {
+ // logger.error("Interruption Exception in createKafkaTopics. Unable to List existing Topics", e);
+ // } catch (ExecutionException e) {
+ // logger.error("Execution Exception in createKafkaTopics. Unable to List existing Topics", e);
+ // }
+
+
+ return new NewTopics(newTopics.toArray(NewTopic[]::new));
+ }
+
+ @Bean
+ public ProducerFactory producerFactory() {
+ Properties configProps = properties.createStreamProperties("Deduplicator-producer-factory");
+
+ Map map = new HashMap<>();
+
+ for (Map.Entry entry : configProps.entrySet()) {
+ String key = (String) entry.getKey();
+ Object value = entry.getValue();
+ map.put(key, value);
+ }
+
+ map.put(
+ ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
+ StringSerializer.class);
+ map.put(
+ ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
+ StringSerializer.class);
+
+ return new DefaultKafkaProducerFactory(map);
+ }
+
+ @Bean
+ public KafkaTemplate kafkaTemplate() {
+ return new KafkaTemplate<>(producerFactory());
+ }
+
+ private static final Logger logger = LoggerFactory.getLogger(KafkaConfiguration.class);
+
+ private boolean autoCreateTopics;
+ private int numPartitions;
+ private int numReplicas;
+ private List> createTopics;
+
+ public boolean getAutoCreateTopics() {
+ return autoCreateTopics;
+ }
+
+ public void setAutoCreateTopics(boolean autoCreateTopics) {
+ this.autoCreateTopics = autoCreateTopics;
+ }
+
+ public int getNumPartitions() {
+ return numPartitions;
+ }
+
+ public int getNumReplicas() {
+ return numReplicas;
+ }
+
+ public List> getCreateTopics() {
+ return createTopics;
+ }
+
+ public void setNumPartitions(int numPartitions) {
+ this.numPartitions = numPartitions;
+ logger.info("kafka.topics.numPartitions = {}", numPartitions);
+ }
+
+ public void setNumReplicas(int numReplicas) {
+ this.numReplicas = numReplicas;
+ }
+
+ public void setCreateTopics(List> createTopics) {
+ this.createTopics = createTopics;
+ }
+
+
+
+ @Autowired
+ private KafkaAdmin admin;
+
+
+
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/StreamsExceptionHandler.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/StreamsExceptionHandler.java
new file mode 100644
index 0000000..71132f3
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/StreamsExceptionHandler.java
@@ -0,0 +1,56 @@
+package us.dot.its.jpo.deduplicator;
+
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.kafka.core.KafkaTemplate;
+
+
+
+/**
+ * Handler for unhandled exceptions thrown from Streams topologies that
+ * logs the exception to a topic, and allows choosing the shutdown behavior.
+ *
+ * See {@link https://cwiki.apache.org/confluence/display/KAFKA/KIP-671%3A+Introduce+Kafka+Streams+Specific+Uncaught+Exception+Handler}
+ * for a description of the options.
+ */
+public class StreamsExceptionHandler implements StreamsUncaughtExceptionHandler {
+
+ final static Logger logger = LoggerFactory.getLogger(StreamsExceptionHandler.class);
+
+ final KafkaTemplate kafkaTemplate;
+ final String topology;
+ final String notificationTopic;
+
+ @Autowired
+ public StreamsExceptionHandler(KafkaTemplate kafkaTemplate, String topology, String notificationTopic) {
+ this.kafkaTemplate = kafkaTemplate;
+ this.topology = topology;
+ this.notificationTopic = notificationTopic;
+ }
+
+ @Override
+ public StreamThreadExceptionResponse handle(Throwable exception) {
+ try {
+ logger.error(String.format("Uncaught exception in stream topology %s", topology), exception);
+ } catch (Exception ex) {
+ logger.error("Exception sending kafka streams error event", ex);
+ }
+
+
+ // SHUTDOWN_CLIENT option shuts down quickly.
+ return StreamThreadExceptionResponse.SHUTDOWN_CLIENT;
+
+ // SHUTDOWN_APPLICATION shuts down more slowly, but cleans up more thoroughly
+ //return StreamThreadExceptionResponse.SHUTDOWN_APPLICATION;
+
+ // "Replace Thread" mode can be used to keep the streams client alive,
+ // however if the cause of the error was not transient, but due to a code error processing
+ // a record, it can result in the record being repeatedly processed throwing the
+ // same error
+ //
+ //return StreamThreadExceptionResponse.REPLACE_THREAD;
+ }
+
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/BoundedMemoryRocksDBConfig.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/BoundedMemoryRocksDBConfig.java
new file mode 100644
index 0000000..2c31ce7
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/BoundedMemoryRocksDBConfig.java
@@ -0,0 +1,144 @@
+package us.dot.its.jpo.deduplicator.deduplicator;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.kafka.streams.state.RocksDBConfigSetter;
+import org.rocksdb.BlockBasedTableConfig;
+import org.rocksdb.CompressionType;
+import org.rocksdb.Options;
+import org.rocksdb.RocksDB;
+import java.util.Map;
+
+/**
+ * Bounded memory configuration for RocksDB for all topologies.
+ * References:
+ *
+ * Configured using environment variables:
+ *
+ * DEDUPLICATOR_ROCKSDB_TOTAL_OFF_HEAP_MEMORY Total block cache size
+ * DEDUPLICATOR_ROCKSDB_INDEX_FILTER_BLOCK_RATIO Fraction of the block cache to use for high priority blocks (index
+ * and filter blocks).
+ * DEDUPLICATOR_ROCKSDB_TOTAL_MEMTABLE_MEMORY Write buffer size, include in block cache
+ * DEDUPLICATOR_ROCKSDB_BLOCK_SIZE {@link org.rocksdb.BlockBasedTableConfig#blockSize()}, Default 4KB
+ * DEDUPLICATOR_ROCKSDB_N_MEMTABLES {@link org.rocksdb.Options#maxWriteBufferNumber()}, Default 2
+ * DEDUPLICATOR_ROCKSDB_MEMTABLE_SIZE {@link org.rocksdb.Options#writeBufferSize()}, Default 64MB
+ *
+ *
+ */
+
+@Slf4j
+public class BoundedMemoryRocksDBConfig implements RocksDBConfigSetter {
+
+ private final static long TOTAL_OFF_HEAP_MEMORY;
+ private final static double INDEX_FILTER_BLOCK_RATIO;
+ private final static long TOTAL_MEMTABLE_MEMORY;
+
+ // Block size: Default 4K
+ private final static long BLOCK_SIZE;
+
+ // MaxWriteBufferNumber: Default 2
+ private final static int N_MEMTABLES;
+
+ // WriteBufferSize: Default 64MB
+ private final static long MEMTABLE_SIZE;
+ private final static long KB = 1024L;
+ private final static long MB = KB * KB;
+
+ static {
+ RocksDB.loadLibrary();
+ // Initialize properties from env variables
+ TOTAL_OFF_HEAP_MEMORY = getEnvLong("DEDUPLICATOR_ROCKSDB_TOTAL_OFF_HEAP_MEMORY", 128 * MB);
+ INDEX_FILTER_BLOCK_RATIO = getEnvDouble("DEDUPLICATOR_ROCKSDB_INDEX_FILTER_BLOCK_RATIO", 0.1);
+ TOTAL_MEMTABLE_MEMORY = getEnvLong("DEDUPLICATOR_ROCKSDB_TOTAL_MEMTABLE_MEMORY", 64 * MB);
+ BLOCK_SIZE = getEnvLong("DEDUPLICATOR_ROCKSDB_BLOCK_SIZE", 4 * KB);
+ N_MEMTABLES = getEnvInt("DEDUPLICATOR_ROCKSDB_N_MEMTABLES", 2);
+ MEMTABLE_SIZE = getEnvLong("DEDUPLICATOR_ROCKSDB_MEMTABLE_SIZE", 16 * MB);
+
+ log.info("Initialized BoundedMemoryRocksDBConfig. TOTAL_OFF_HEAP_MEMORY = {}, INDEX_FILTER_BLOCK_RATIO = {}," +
+ " TOTAL_MEMTABLE_MEMORY = {}, BLOCK_SIZE = {}, N_MEMTABLES = {}, MEMTABLE_SIZE = {}",
+ TOTAL_OFF_HEAP_MEMORY, INDEX_FILTER_BLOCK_RATIO, TOTAL_MEMTABLE_MEMORY, BLOCK_SIZE, N_MEMTABLES,
+ MEMTABLE_SIZE);
+ }
+
+ // See #1 below
+ private static final org.rocksdb.Cache cache
+ = new org.rocksdb.LRUCache(TOTAL_OFF_HEAP_MEMORY, -1, false, INDEX_FILTER_BLOCK_RATIO);
+ private static final org.rocksdb.WriteBufferManager writeBufferManager
+ = new org.rocksdb.WriteBufferManager(TOTAL_MEMTABLE_MEMORY, cache);
+ @Override
+ public void setConfig(final String storeName, final Options options, final Map configs) {
+ log.info("Setting RocksDB config for store {}", storeName);
+ BlockBasedTableConfig tableConfig = (BlockBasedTableConfig) options.tableFormatConfig();
+
+ // These three options in combination will limit the memory used by RocksDB to the size passed to the block
+ // cache (TOTAL_OFF_HEAP_MEMORY)
+ tableConfig.setBlockCache(cache);
+ tableConfig.setCacheIndexAndFilterBlocks(true);
+ options.setWriteBufferManager(writeBufferManager);
+
+ // These options are recommended to be set when bounding the total memory
+ // See #2 below
+ tableConfig.setCacheIndexAndFilterBlocksWithHighPriority(true);
+ tableConfig.setPinTopLevelIndexAndFilter(true);
+
+ // See #3 below
+ tableConfig.setBlockSize(BLOCK_SIZE);
+ options.setMaxWriteBufferNumber(N_MEMTABLES);
+ options.setWriteBufferSize(MEMTABLE_SIZE);
+
+ // Enable compression (optional). Compression can decrease the required storage
+ // and increase the CPU usage of the machine. For CompressionType values, see
+ // https://javadoc.io/static/org.rocksdb/rocksdbjni/6.4.6/org/rocksdb/CompressionType.html.
+ options.setCompressionType(CompressionType.LZ4_COMPRESSION);
+ options.setTableFormatConfig(tableConfig);
+ log.info("Rocksdb set table config: {}, options: {}", tableConfig, options);
+ }
+ @Override
+ public void close(final String storeName, final Options options) {
+ // Cache and WriteBufferManager should not be closed here, as the same objects are shared by every store instance.
+ }
+
+ private static long getEnvLong(String name, long defaultValue) {
+ String strValue = getEnvString(name);
+ if (strValue == null) return defaultValue;
+
+ try {
+ return Long.parseLong(strValue);
+ } catch (NumberFormatException nfe) {
+ log.error("Error parsing env variable to long {}, {}", name, strValue, nfe);
+ return defaultValue;
+ }
+ }
+
+ private static int getEnvInt(String name, int defaultValue) {
+ String strValue = getEnvString(name);
+ if (strValue == null) return defaultValue;
+ try {
+ return Integer.parseInt(strValue);
+ } catch (NumberFormatException nfe) {
+ log.error("Error parsing env variable to long {}, {}", name, strValue, nfe);
+ return defaultValue;
+ }
+ }
+
+ private static double getEnvDouble(String name, double defaultValue) {
+ String strValue = getEnvString(name);
+ if (strValue == null) return defaultValue;
+ try {
+ return Double.parseDouble(strValue);
+ } catch (NumberFormatException nfe) {
+ log.error("Error parsing env variable to long {}, {}", name, strValue, nfe);
+ return defaultValue;
+ }
+ }
+
+ private static String getEnvString(String name) {
+ String strValue = System.getenv(name);
+ if (strValue == null) {
+ log.warn("Env variable {} is not set", name);
+ }
+ return strValue;
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/DeduplicatorServiceController.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/DeduplicatorServiceController.java
new file mode 100644
index 0000000..bd38ab9
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/DeduplicatorServiceController.java
@@ -0,0 +1,114 @@
+package us.dot.its.jpo.deduplicator.deduplicator;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.kafka.streams.KafkaStreams;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.context.annotation.Profile;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.stereotype.Controller;
+
+import lombok.Getter;
+import us.dot.its.jpo.conflictmonitor.monitor.MonitorServiceController;
+import us.dot.its.jpo.conflictmonitor.monitor.algorithms.StreamsTopology;
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.BsmDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.MapDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.TimDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.OdeRawEncodedTimDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedMapDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedMapWktDeduplicatorTopology;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedSpatDeduplicatorTopology;
+
+@Controller
+@DependsOn("createKafkaTopics")
+@Profile("!test && !testConfig")
+public class DeduplicatorServiceController {
+
+ private static final Logger logger = LoggerFactory.getLogger(MonitorServiceController.class);
+
+ // Temporary for KafkaStreams that don't implement the Algorithm interface
+ @Getter
+ final ConcurrentHashMap streamsMap = new ConcurrentHashMap();
+
+ @Getter
+ final ConcurrentHashMap algoMap = new ConcurrentHashMap();
+
+
+
+ @Autowired
+ public DeduplicatorServiceController(final DeduplicatorProperties props,
+ final KafkaTemplate kafkaTemplate) {
+
+
+ try {
+
+ if(props.isEnableProcessedMapDeduplication()){
+ logger.info("Starting Processed Map Deduplicator");
+ ProcessedMapDeduplicatorTopology processedMapDeduplicatorTopology = new ProcessedMapDeduplicatorTopology(
+ props,
+ props.createStreamProperties("ProcessedMapDeduplicator")
+ );
+ processedMapDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableProcessedMapWktDeduplication()){
+ logger.info("Starting Processed Map WKT Deduplicator");
+ ProcessedMapWktDeduplicatorTopology processedMapWktDeduplicatorTopology = new ProcessedMapWktDeduplicatorTopology(
+ props,
+ props.createStreamProperties("ProcessedMapWKTdeduplicator")
+ );
+ processedMapWktDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableProcessedMapDeduplication()){
+ logger.info("Starting Map Deduplicator");
+ MapDeduplicatorTopology mapDeduplicatorTopology = new MapDeduplicatorTopology(
+ props,
+ props.createStreamProperties("MapDeduplicator")
+ );
+ mapDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableOdeTimDeduplication()){
+ logger.info("Starting Tim Deduplicator");
+ TimDeduplicatorTopology timDeduplicatorTopology = new TimDeduplicatorTopology(
+ props,
+ props.createStreamProperties("TimDeduplicator")
+ );
+ timDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableOdeRawEncodedTimDeduplication()){
+ logger.info("Starting Raw Encoded TIM Deduplicator");
+ OdeRawEncodedTimDeduplicatorTopology odeRawEncodedTimDeduplicatorTopology = new OdeRawEncodedTimDeduplicatorTopology(
+ props,
+ props.createStreamProperties("OdeRawEncodedTimDeduplicator")
+ );
+ odeRawEncodedTimDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableProcessedSpatDeduplication()){
+ logger.info("Starting Processed Spat Deduplicator");
+ ProcessedSpatDeduplicatorTopology processedSpatDeduplicatorTopology = new ProcessedSpatDeduplicatorTopology(
+ props,
+ props.createStreamProperties("ProcessedSpatDeduplicator")
+ );
+ processedSpatDeduplicatorTopology.start();
+ }
+
+ if(props.isEnableOdeBsmDeduplication()){
+ logger.info("Starting BSM Deduplicator");
+ BsmDeduplicatorTopology bsmDeduplicatorTopology = new BsmDeduplicatorTopology(props);
+ bsmDeduplicatorTopology.start();
+ }
+
+
+ } catch (Exception e) {
+ logger.error("Encountered issue with creating topologies", e);
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/JsonPair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/JsonPair.java
new file mode 100644
index 0000000..d0f4377
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/JsonPair.java
@@ -0,0 +1,21 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class JsonPair {
+
+ public JsonNode message;
+ public boolean shouldSend;
+
+ public JsonPair(JsonNode message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeBsmPair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeBsmPair.java
new file mode 100644
index 0000000..208622b
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeBsmPair.java
@@ -0,0 +1,20 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import us.dot.its.jpo.ode.model.OdeBsmData;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class OdeBsmPair {
+
+ public OdeBsmData message;
+ public boolean shouldSend;
+
+ public OdeBsmPair(OdeBsmData message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeMapPair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeMapPair.java
new file mode 100644
index 0000000..24c265a
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/OdeMapPair.java
@@ -0,0 +1,20 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import us.dot.its.jpo.ode.model.OdeMapData;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class OdeMapPair {
+
+ public OdeMapData message;
+ public boolean shouldSend;
+
+ public OdeMapPair(OdeMapData message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/Pair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/Pair.java
new file mode 100644
index 0000000..fd0ee44
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/Pair.java
@@ -0,0 +1,19 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class Pair {
+
+ public T message;
+ public boolean shouldSend;
+
+ public Pair(T message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapPair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapPair.java
new file mode 100644
index 0000000..b1400c5
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapPair.java
@@ -0,0 +1,21 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class ProcessedMapPair {
+
+ public ProcessedMap message;
+ public boolean shouldSend;
+
+ public ProcessedMapPair(ProcessedMap message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapWktPair.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapWktPair.java
new file mode 100644
index 0000000..d6acaca
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/models/ProcessedMapWktPair.java
@@ -0,0 +1,20 @@
+package us.dot.its.jpo.deduplicator.deduplicator.models;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+@NoArgsConstructor
+@Setter
+@Getter
+public class ProcessedMapWktPair {
+
+ public ProcessedMap message;
+ public boolean shouldSend;
+
+ public ProcessedMapWktPair(ProcessedMap message, boolean shouldSend){
+ this.message = message;
+ this.shouldSend = shouldSend;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/DeduplicationProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/DeduplicationProcessor.java
new file mode 100644
index 0000000..55b669c
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/DeduplicationProcessor.java
@@ -0,0 +1,69 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+
+import org.apache.kafka.streams.processor.PunctuationType;
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorContext;
+import org.apache.kafka.streams.processor.api.Record;
+import org.apache.kafka.streams.state.KeyValueStore;
+
+import org.apache.kafka.streams.state.KeyValueIterator;
+import org.apache.kafka.streams.KeyValue;
+
+public abstract class DeduplicationProcessor implements Processor{
+
+ private ProcessorContext context;
+ private KeyValueStore store;
+ public String storeName;
+
+ @Override
+ public void init(ProcessorContext context) {
+ this.context = context;
+ store = context.getStateStore(storeName);
+ this.context.schedule(Duration.ofHours(1), PunctuationType.WALL_CLOCK_TIME, this::cleanupOldKeys);
+ }
+
+ @Override
+ public void process(Record record) {
+
+ // Don't do anything if key is bad
+ if(record.key().equals("")){
+ return;
+ }
+
+ T lastRecord = store.get(record.key());
+ if(lastRecord == null){
+ store.put(record.key(), record.value());
+ context.forward(record);
+ return;
+ }
+
+ if(!isDuplicate(lastRecord, record.value())){
+ store.put(record.key(), record.value());
+ context.forward(record);
+ return;
+ }
+ }
+
+ private void cleanupOldKeys(final long timestamp) {
+ try (KeyValueIterator iterator = store.all()) {
+ while (iterator.hasNext()) {
+
+ KeyValue record = iterator.next();
+ // Delete any record more than 2 hours old.
+ if(Instant.ofEpochMilli(timestamp).minusSeconds(2 * 60 * 60).isAfter(getMessageTime(record.value))){
+ store.delete(record.key);
+ }
+ }
+ }
+ }
+
+ // returns an instant representing the time of the message
+ public abstract Instant getMessageTime(T message);
+
+ // returns if two messages are duplicates of one another
+ public abstract boolean isDuplicate(T lastMessage, T newMessage);
+
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeBsmJsonProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeBsmJsonProcessor.java
new file mode 100644
index 0000000..16a621c
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeBsmJsonProcessor.java
@@ -0,0 +1,84 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+import org.geotools.referencing.GeodeticCalculator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.ode.model.OdeBsmData;
+import us.dot.its.jpo.ode.model.OdeBsmMetadata;
+import us.dot.its.jpo.ode.plugin.j2735.J2735Bsm;
+import us.dot.its.jpo.ode.plugin.j2735.J2735BsmCoreData;
+
+public class OdeBsmJsonProcessor extends DeduplicationProcessor{
+
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ DeduplicatorProperties props;
+ GeodeticCalculator calculator;
+
+ private static final Logger logger = LoggerFactory.getLogger(OdeBsmJsonProcessor.class);
+
+ public OdeBsmJsonProcessor(String storeName, DeduplicatorProperties props){
+ this.storeName = storeName;
+ this.props = props;
+ calculator = new GeodeticCalculator();
+ }
+
+
+ @Override
+ public Instant getMessageTime(OdeBsmData message) {
+ String time = ((OdeBsmMetadata)message.getMetadata()).getOdeReceivedAt();
+ try {
+ return Instant.from(formatter.parse(time));
+ } catch (Exception e) {
+ logger.warn("Failed to Parse Time: " + time);
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(OdeBsmData lastMessage, OdeBsmData newMessage) {
+ Instant newValueTime = getMessageTime(newMessage);
+ Instant oldValueTime = getMessageTime(lastMessage);
+
+ // If the messages are more than a certain time apart, forward the new message on
+ if(newValueTime.minus(Duration.ofMillis(props.getOdeBsmMaximumTimeDelta())).isAfter(oldValueTime)){
+ return false;
+ }
+
+ J2735BsmCoreData oldCore = ((J2735Bsm)lastMessage.getPayload().getData()).getCoreData();
+ J2735BsmCoreData newCore = ((J2735Bsm)newMessage.getPayload().getData()).getCoreData();
+
+
+ // If the Vehicle is moving, forward the message on
+ if(newCore.getSpeed().doubleValue() > props.getOdeBsmAlwaysIncludeAtSpeed()){
+ return false;
+ }
+
+
+ double distance = calculateGeodeticDistance(
+ newCore.getPosition().getLatitude().doubleValue(),
+ newCore.getPosition().getLongitude().doubleValue(),
+ oldCore.getPosition().getLatitude().doubleValue(),
+ oldCore.getPosition().getLongitude().doubleValue()
+ );
+
+ // If the position delta between the messages is suitable large, forward the message on
+ if(distance > props.getOdeBsmMaximumPositionDelta()){
+ return false;
+ }
+
+ return true;
+ }
+
+ public double calculateGeodeticDistance(double lat1, double lon1, double lat2, double lon2) {
+ calculator.setStartingGeographicPoint(lon1, lat1);
+ calculator.setDestinationGeographicPoint(lon2, lat2);
+ return calculator.getOrthodromicDistance();
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeMapJsonProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeMapJsonProcessor.java
new file mode 100644
index 0000000..adaf6db
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeMapJsonProcessor.java
@@ -0,0 +1,70 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.ode.model.OdeMapData;
+import us.dot.its.jpo.ode.model.OdeMapMetadata;
+import us.dot.its.jpo.ode.model.OdeMapPayload;
+
+public class OdeMapJsonProcessor extends DeduplicationProcessor{
+
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+
+ DeduplicatorProperties props;
+
+ public OdeMapJsonProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreOdeMapJsonName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(OdeMapData message) {
+ try {
+ String time = ((OdeMapMetadata)message.getMetadata()).getOdeReceivedAt();
+ return Instant.from(formatter.parse(time));
+ } catch (Exception e) {
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(OdeMapData lastMessage, OdeMapData newMessage) {
+
+ Instant newValueTime = getMessageTime(newMessage);
+ Instant oldValueTime = getMessageTime(lastMessage);
+
+ if(newValueTime.minus(Duration.ofHours(1)).isAfter(oldValueTime)){
+ return false;
+
+ }else{
+ OdeMapPayload oldPayload = (OdeMapPayload)lastMessage.getPayload();
+ OdeMapPayload newPayload = (OdeMapPayload)newMessage.getPayload();
+
+ Integer oldTimestamp = oldPayload.getMap().getTimeStamp();
+ Integer newTimestamp = newPayload.getMap().getTimeStamp();
+
+
+ newPayload.getMap().setTimeStamp(oldTimestamp);
+
+ int oldHash = hashMapMessage(lastMessage);
+ int newhash = hashMapMessage(newMessage);
+
+ if(oldHash != newhash){
+ newPayload.getMap().setTimeStamp(newTimestamp);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public int hashMapMessage(OdeMapData map){
+ OdeMapPayload payload = (OdeMapPayload)map.getPayload();
+ return Objects.hash(payload.toJson());
+
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeRawEncodedTimJsonProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeRawEncodedTimJsonProcessor.java
new file mode 100644
index 0000000..cca49a7
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeRawEncodedTimJsonProcessor.java
@@ -0,0 +1,43 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+
+public class OdeRawEncodedTimJsonProcessor extends DeduplicationProcessor{
+
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+
+ DeduplicatorProperties props;
+
+ public OdeRawEncodedTimJsonProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreOdeRawEncodedTimJsonName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(JsonNode message) {
+ try {
+ String time = message.get("metadata").get("odeReceivedAt").asText();
+ return Instant.from(formatter.parse(time));
+ } catch (Exception e) {
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(JsonNode lastMessage, JsonNode newMessage) {
+ Instant oldValueTime = getMessageTime(lastMessage);
+ Instant newValueTime = getMessageTime(newMessage);
+
+ if(newValueTime.minus(Duration.ofHours(1)).isAfter(oldValueTime)){
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeTimJsonProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeTimJsonProcessor.java
new file mode 100644
index 0000000..9a117b3
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/OdeTimJsonProcessor.java
@@ -0,0 +1,43 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.ode.model.OdeTimData;
+import us.dot.its.jpo.ode.model.OdeTimMetadata;
+
+public class OdeTimJsonProcessor extends DeduplicationProcessor{
+
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+
+ DeduplicatorProperties props;
+ public OdeTimJsonProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreOdeTimJsonName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(OdeTimData message) {
+ try {
+ // String time = message.get("metadata").get("odeReceivedAt").asText();
+ String time = ((OdeTimMetadata)message.getMetadata()).getOdeReceivedAt();
+ return Instant.from(formatter.parse(time));
+ } catch (Exception e) {
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(OdeTimData lastMessage, OdeTimData newMessage) {
+ Instant oldValueTime = getMessageTime(lastMessage);
+ Instant newValueTime = getMessageTime(newMessage);
+
+ if(newValueTime.minus(Duration.ofHours(1)).isAfter(oldValueTime)){
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapProcessor.java
new file mode 100644
index 0000000..35e2c2f
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapProcessor.java
@@ -0,0 +1,57 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import java.util.Objects;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+public class ProcessedMapProcessor extends DeduplicationProcessor>{
+
+ DeduplicatorProperties props;
+
+ public ProcessedMapProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreProcessedMapName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(ProcessedMap message) {
+ try {
+ return message.getProperties().getOdeReceivedAt().toInstant();
+ } catch (Exception e) {
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(ProcessedMap lastMessage, ProcessedMap newMessage) {
+
+ Instant newValueTime = getMessageTime(newMessage);
+ Instant oldValueTime = getMessageTime(lastMessage);
+
+ if(newValueTime.minus(Duration.ofHours(1)).isAfter(oldValueTime)){
+ return false;
+ }else{
+ ZonedDateTime newValueTimestamp = newMessage.getProperties().getTimeStamp();
+ ZonedDateTime newValueOdeReceivedAt = newMessage.getProperties().getOdeReceivedAt();
+
+ newMessage.getProperties().setTimeStamp(lastMessage.getProperties().getTimeStamp());
+ newMessage.getProperties().setOdeReceivedAt(lastMessage.getProperties().getOdeReceivedAt());
+
+ int oldHash = Objects.hash(lastMessage.toString());
+ int newHash = Objects.hash(newMessage.toString());
+
+ if(oldHash != newHash){
+ newMessage.getProperties().setTimeStamp(newValueTimestamp);
+ newMessage.getProperties().setOdeReceivedAt(newValueOdeReceivedAt);
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapWktProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapWktProcessor.java
new file mode 100644
index 0000000..7556060
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedMapWktProcessor.java
@@ -0,0 +1,55 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.time.ZonedDateTime;
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+public class ProcessedMapWktProcessor extends DeduplicationProcessor>{
+
+ DeduplicatorProperties props;
+
+ public ProcessedMapWktProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreProcessedMapWKTName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(ProcessedMap message) {
+ try {
+ return message.getProperties().getOdeReceivedAt().toInstant();
+ } catch (Exception e) {
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+ @Override
+ public boolean isDuplicate(ProcessedMap lastMessage, ProcessedMap newMessage) {
+
+ Instant newValueTime = newMessage.getProperties().getTimeStamp().toInstant();
+ Instant oldValueTime = lastMessage.getProperties().getTimeStamp().toInstant();
+
+ if(newValueTime.minus(Duration.ofHours(1)).isAfter(oldValueTime)){
+ return false;
+ }else{
+ ZonedDateTime newValueTimestamp = newMessage.getProperties().getTimeStamp();
+ ZonedDateTime newValueOdeReceivedAt = newMessage.getProperties().getOdeReceivedAt();
+
+ newMessage.getProperties().setTimeStamp(lastMessage.getProperties().getTimeStamp());
+ newMessage.getProperties().setOdeReceivedAt(lastMessage.getProperties().getOdeReceivedAt());
+
+ int oldHash = lastMessage.getProperties().hashCode();
+ int newhash = newMessage.getProperties().hashCode();
+
+ if(oldHash != newhash){
+ newMessage.getProperties().setTimeStamp(newValueTimestamp);
+ newMessage.getProperties().setOdeReceivedAt(newValueOdeReceivedAt);
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedSpatProcessor.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedSpatProcessor.java
new file mode 100644
index 0000000..2cc58af
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/ProcessedSpatProcessor.java
@@ -0,0 +1,64 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors;
+
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.HashMap;
+import java.util.List;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.MovementEvent;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.MovementState;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.ProcessedSpat;
+
+public class ProcessedSpatProcessor extends DeduplicationProcessor{
+
+ DeduplicatorProperties props;
+
+ public ProcessedSpatProcessor(DeduplicatorProperties props){
+ this.props = props;
+ this.storeName = props.getKafkaStateStoreProcessedSpatName();
+ }
+
+
+ @Override
+ public Instant getMessageTime(ProcessedSpat message) {
+ return message.getUtcTimeStamp().toInstant();
+ }
+
+ @Override
+ public boolean isDuplicate(ProcessedSpat lastMessage, ProcessedSpat newMessage) {
+
+ Instant newValueTime = getMessageTime(newMessage);
+ Instant oldValueTime = getMessageTime(lastMessage);
+
+ if(newValueTime.minus(Duration.ofMinutes(1)).isAfter(oldValueTime)){
+ return false;
+ }else{
+ HashMap> lastMessageStates = new HashMap<>();
+ for(MovementState state: lastMessage.getStates()){
+ lastMessageStates.put(state.getSignalGroup(), state.getStateTimeSpeed());
+ }
+
+ if(lastMessageStates.size() != newMessage.getStates().size()){
+ return false; // message cannot be duplicate if the signal groups have a different number of signal groups
+ }
+
+ for(MovementState state: newMessage.getStates()){
+ List lastMessageState = lastMessageStates.get(state.getSignalGroup());
+
+ if(lastMessageState == null){
+ return false; // messages cannot be duplicates if they have different signal groups
+ }
+
+
+ for(int i=0; i< state.getStateTimeSpeed().size(); i++){
+ if(state.getStateTimeSpeed().get(i).getEventState() != lastMessageState.get(i).getEventState()){
+ return false; // Some signal group light has changed. Therefore the SPaTs are different
+ }
+ }
+ }
+ }
+ return true;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeBsmJsonProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeBsmJsonProcessorSupplier.java
new file mode 100644
index 0000000..6b08b9f
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeBsmJsonProcessorSupplier.java
@@ -0,0 +1,26 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import java.time.format.DateTimeFormatter;
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.OdeBsmJsonProcessor;
+import us.dot.its.jpo.ode.model.OdeBsmData;
+
+public class OdeBsmJsonProcessorSupplier implements ProcessorSupplier {
+
+ String storeName;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ DeduplicatorProperties props;
+
+ public OdeBsmJsonProcessorSupplier(String storeName, DeduplicatorProperties props){
+ this.storeName = storeName;
+ this.props = props;
+ }
+
+ @Override
+ public Processor get() {
+ return new OdeBsmJsonProcessor(storeName, props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeMapJsonProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeMapJsonProcessorSupplier.java
new file mode 100644
index 0000000..829af13
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeMapJsonProcessorSupplier.java
@@ -0,0 +1,22 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.OdeMapJsonProcessor;
+import us.dot.its.jpo.ode.model.OdeMapData;
+
+public class OdeMapJsonProcessorSupplier implements ProcessorSupplier {
+
+ DeduplicatorProperties props;
+
+ public OdeMapJsonProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor get() {
+ return new OdeMapJsonProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeRawEncodedTimProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeRawEncodedTimProcessorSupplier.java
new file mode 100644
index 0000000..ef0ebb7
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeRawEncodedTimProcessorSupplier.java
@@ -0,0 +1,22 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+import com.fasterxml.jackson.databind.JsonNode;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.OdeRawEncodedTimJsonProcessor;
+
+public class OdeRawEncodedTimProcessorSupplier implements ProcessorSupplier {
+
+ DeduplicatorProperties props;
+
+ public OdeRawEncodedTimProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor get() {
+ return new OdeRawEncodedTimJsonProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeTimJsonProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeTimJsonProcessorSupplier.java
new file mode 100644
index 0000000..0c07e30
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/OdeTimJsonProcessorSupplier.java
@@ -0,0 +1,22 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.OdeTimJsonProcessor;
+import us.dot.its.jpo.ode.model.OdeTimData;
+
+public class OdeTimJsonProcessorSupplier implements ProcessorSupplier {
+
+ String storeName;
+ DeduplicatorProperties props;
+ public OdeTimJsonProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor get() {
+ return new OdeTimJsonProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapProcessorSupplier.java
new file mode 100644
index 0000000..9e45cd0
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapProcessorSupplier.java
@@ -0,0 +1,23 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.ProcessedMapProcessor;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+public class ProcessedMapProcessorSupplier implements ProcessorSupplier, String, ProcessedMap> {
+
+ DeduplicatorProperties props;
+
+ public ProcessedMapProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor, String, ProcessedMap> get() {
+ return new ProcessedMapProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapWktProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapWktProcessorSupplier.java
new file mode 100644
index 0000000..3dbaa8c
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedMapWktProcessorSupplier.java
@@ -0,0 +1,22 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.ProcessedMapWktProcessor;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+
+public class ProcessedMapWktProcessorSupplier implements ProcessorSupplier, String, ProcessedMap> {
+
+ DeduplicatorProperties props;
+
+ public ProcessedMapWktProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor, String, ProcessedMap> get() {
+ return new ProcessedMapWktProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedSpatProcessorSupplier.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedSpatProcessorSupplier.java
new file mode 100644
index 0000000..e6661ac
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/processors/suppliers/ProcessedSpatProcessorSupplier.java
@@ -0,0 +1,22 @@
+package us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers;
+
+import org.apache.kafka.streams.processor.api.Processor;
+import org.apache.kafka.streams.processor.api.ProcessorSupplier;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.ProcessedSpatProcessor;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.ProcessedSpat;
+
+public class ProcessedSpatProcessorSupplier implements ProcessorSupplier {
+
+ DeduplicatorProperties props;
+
+ public ProcessedSpatProcessorSupplier(DeduplicatorProperties props){
+ this.props = props;
+ }
+
+ @Override
+ public Processor get() {
+ return new ProcessedSpatProcessor(props);
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/JsonSerdes.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/JsonSerdes.java
new file mode 100644
index 0000000..29c9778
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/JsonSerdes.java
@@ -0,0 +1,24 @@
+package us.dot.its.jpo.deduplicator.deduplicator.serialization;
+
+import org.apache.kafka.common.serialization.Serde;
+import org.apache.kafka.common.serialization.Serdes;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+import us.dot.its.jpo.geojsonconverter.serialization.deserializers.JsonDeserializer;
+import us.dot.its.jpo.geojsonconverter.serialization.serializers.JsonSerializer;
+import us.dot.its.jpo.ode.model.OdeTimData;
+
+public class JsonSerdes {
+ public static Serde OdeTim() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(OdeTimData.class));
+ }
+
+ public static Serde JSON(){
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(JsonNode.class));
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/PairSerdes.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/PairSerdes.java
new file mode 100644
index 0000000..e509fa0
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/serialization/PairSerdes.java
@@ -0,0 +1,52 @@
+package us.dot.its.jpo.deduplicator.deduplicator.serialization;
+
+import org.apache.kafka.common.serialization.Serde;
+import org.apache.kafka.common.serialization.Serdes;
+
+import us.dot.its.jpo.deduplicator.deduplicator.models.ProcessedMapPair;
+import us.dot.its.jpo.deduplicator.deduplicator.models.ProcessedMapWktPair;
+import us.dot.its.jpo.deduplicator.deduplicator.models.OdeMapPair;
+import us.dot.its.jpo.deduplicator.deduplicator.models.OdeBsmPair;
+import us.dot.its.jpo.deduplicator.deduplicator.models.JsonPair;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.DeserializedRawMap;
+import us.dot.its.jpo.geojsonconverter.serialization.deserializers.JsonDeserializer;
+import us.dot.its.jpo.geojsonconverter.serialization.serializers.JsonSerializer;
+
+
+public class PairSerdes {
+ public static Serde ProcessedMapPair() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(ProcessedMapPair.class));
+ }
+
+ public static Serde ProcessedMapWktPair() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(ProcessedMapWktPair.class));
+ }
+
+ public static Serde OdeMapPair() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(OdeMapPair.class));
+ }
+
+ public static Serde OdeBsmPair() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(OdeBsmPair.class));
+ }
+
+ public static Serde RawMap() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(DeserializedRawMap.class));
+ }
+
+ public static Serde JsonPair() {
+ return Serdes.serdeFrom(
+ new JsonSerializer(),
+ new JsonDeserializer<>(JsonPair.class));
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/BsmDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/BsmDeduplicatorTopology.java
new file mode 100644
index 0000000..6b26d67
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/BsmDeduplicatorTopology.java
@@ -0,0 +1,125 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.conflictmonitor.monitor.serialization.JsonSerdes;
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.ode.model.OdeBsmData;
+import us.dot.its.jpo.ode.model.OdeBsmMetadata;
+import us.dot.its.jpo.ode.model.OdeMapData;
+import us.dot.its.jpo.ode.model.OdeMapPayload;
+import us.dot.its.jpo.ode.plugin.j2735.J2735Bsm;
+import us.dot.its.jpo.ode.plugin.j2735.J2735BsmCoreData;
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.geotools.referencing.GeodeticCalculator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.OdeBsmJsonProcessorSupplier;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+
+public class BsmDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(BsmDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ DeduplicatorProperties props;
+ ObjectMapper objectMapper;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ GeodeticCalculator calculator;
+
+
+
+ public BsmDeduplicatorTopology(DeduplicatorProperties props){
+ this.props = props;
+ this.objectMapper = DateJsonMapper.getInstance();
+ calculator = new GeodeticCalculator();
+ }
+
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, props.createStreamProperties("BsmDeduplicator"));
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Bsm Deduplicator Topology");
+ streams.start();
+ }
+
+ public Instant getInstantFromBsm(OdeBsmData bsm){
+ String time = ((OdeBsmMetadata)bsm.getMetadata()).getOdeReceivedAt();
+
+ return Instant.from(formatter.parse(time));
+ }
+
+ public int hashMapMessage(OdeMapData map){
+ OdeMapPayload payload = (OdeMapPayload)map.getPayload();
+ return Objects.hash(payload.toJson());
+
+ }
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream inputStream = builder.stream(this.props.getKafkaTopicOdeBsmJson(), Consumed.with(Serdes.Void(), JsonSerdes.OdeBsm()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreOdeBsmJsonName()),
+ Serdes.String(), JsonSerdes.OdeBsm()));
+
+ KStream bsmRekeyedStream = inputStream.selectKey((key, value)->{
+ J2735BsmCoreData core = ((J2735Bsm)value.getPayload().getData()).getCoreData();
+ return core.getId();
+ }).repartition(Repartitioned.with(Serdes.String(), JsonSerdes.OdeBsm()));
+
+ KStream deduplicatedStream = bsmRekeyedStream.process(new OdeBsmJsonProcessorSupplier(props.getKafkaStateStoreOdeBsmJsonName(), props), props.getKafkaStateStoreOdeBsmJsonName());
+
+
+ deduplicatedStream.to(this.props.getKafkaTopicDeduplicatedOdeBsmJson(), Produced.with(Serdes.String(), JsonSerdes.OdeBsm()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Bsm deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Bsm deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+ public double calculateGeodeticDistance(double lat1, double lon1, double lat2, double lon2) {
+ calculator.setStartingGeographicPoint(lon1, lat1);
+ calculator.setDestinationGeographicPoint(lon2, lat2);
+ return calculator.getOrthodromicDistance();
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/MapDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/MapDeduplicatorTopology.java
new file mode 100644
index 0000000..c8ac7f6
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/MapDeduplicatorTopology.java
@@ -0,0 +1,121 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.OdeMapJsonProcessorSupplier;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+import us.dot.its.jpo.geojsonconverter.partitioner.RsuIntersectionKey;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import us.dot.its.jpo.ode.model.OdeMapData;
+import us.dot.its.jpo.ode.model.OdeMapMetadata;
+import us.dot.its.jpo.ode.model.OdeMapPayload;
+import us.dot.its.jpo.ode.plugin.j2735.J2735IntersectionReferenceID;
+
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+import java.util.Properties;
+
+public class MapDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(MapDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ String inputTopic;
+ String outputTopic;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ DeduplicatorProperties props;
+
+
+ public MapDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties){
+ this.props = props;
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ }
+
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Map Deduplicator Topology");
+ streams.start();
+ }
+
+ public Instant getInstantFromMap(OdeMapData map){
+ String time = ((OdeMapMetadata)map.getMetadata()).getOdeReceivedAt();
+
+ return Instant.from(formatter.parse(time));
+ }
+
+ public int hashMapMessage(OdeMapData map){
+ OdeMapPayload payload = (OdeMapPayload)map.getPayload();
+ return Objects.hash(payload.toJson());
+
+ }
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream inputStream = builder.stream(props.getKafkaTopicOdeMapJson(), Consumed.with(Serdes.Void(), JsonSerdes.OdeMap()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreOdeMapJsonName()),
+ Serdes.String(), JsonSerdes.OdeMap()));
+
+ KStream mapRekeyedStream = inputStream.selectKey((key, value)->{
+ J2735IntersectionReferenceID intersectionId = ((OdeMapPayload)value.getPayload()).getMap().getIntersections().getIntersections().get(0).getId();
+ RsuIntersectionKey newKey = new RsuIntersectionKey();
+ newKey.setRsuId(((OdeMapMetadata)value.getMetadata()).getOriginIp());
+ newKey.setIntersectionReferenceID(intersectionId);
+ return newKey.toString();
+ }).repartition(Repartitioned.with(Serdes.String(), JsonSerdes.OdeMap()));
+
+ KStream deduplicatedStream = mapRekeyedStream.process(new OdeMapJsonProcessorSupplier(props), props.getKafkaStateStoreOdeMapJsonName());
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedOdeMapJson(), Produced.with(Serdes.String(), JsonSerdes.OdeMap()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Map Deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Map Deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/OdeRawEncodedTimDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/OdeRawEncodedTimDeduplicatorTopology.java
new file mode 100644
index 0000000..c68d902
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/OdeRawEncodedTimDeduplicatorTopology.java
@@ -0,0 +1,130 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.serialization.JsonSerdes;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+import java.util.Properties;
+
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.OdeRawEncodedTimProcessorSupplier;
+
+public class OdeRawEncodedTimDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(OdeRawEncodedTimDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ String inputTopic;
+ String outputTopic;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DeduplicatorProperties props;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+
+ public OdeRawEncodedTimDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties){
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ this.props = props;
+ }
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Tim Deduplicator Topology");
+ streams.start();
+ }
+
+ public JsonNode genJsonNode(){
+ return objectMapper.createObjectNode();
+ }
+
+ public Instant getInstantFromJsonTim(JsonNode tim){
+ String time = tim.get("metadata").get("odeReceivedAt").asText();
+ try{
+ return Instant.from(formatter.parse(time));
+ }catch(Exception e){
+ logger.warn("Failed to parse time: " + time);
+ return Instant.ofEpochMilli(0);
+ }
+ }
+
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream inputStream = builder.stream(props.getKafkaTopicOdeRawEncodedTimJson(), Consumed.with(Serdes.Void(), JsonSerdes.JSON()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreOdeRawEncodedTimJsonName()),
+ Serdes.String(), JsonSerdes.JSON()));
+
+ KStream timRekeyedStream = inputStream.selectKey((key, value)->{
+ try{
+ String messageBytes = value.get("payload")
+ .get("data")
+ .get("bytes").asText();
+
+ int hash = Objects.hash(messageBytes);
+
+ String rsuIP = value.get("metadata").get("originIp").asText();
+
+ String newKey = rsuIP + "_" + hash;
+ return newKey;
+ }catch(Exception e){
+ return "";
+ }
+ }).repartition(Repartitioned.with(Serdes.String(), JsonSerdes.JSON()));
+
+
+
+ KStream deduplicatedStream = timRekeyedStream.process(new OdeRawEncodedTimProcessorSupplier(props), props.getKafkaStateStoreOdeRawEncodedTimJsonName());
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedOdeRawEncodedTimJson(), Produced.with(Serdes.String(), JsonSerdes.JSON()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping OdeRawEncodedTim Deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped OdeRawEncodedTim Deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapDeduplicatorTopology.java
new file mode 100644
index 0000000..5f9da3d
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapDeduplicatorTopology.java
@@ -0,0 +1,92 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.ProcessedMapProcessorSupplier;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+
+import java.util.Properties;
+
+public class ProcessedMapDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(MapDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DeduplicatorProperties props;
+
+ public ProcessedMapDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties){
+ this.props = props;
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ }
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Processed Map Deduplicator Topology");
+ streams.start();
+ }
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream> inputStream = builder.stream(props.getKafkaTopicProcessedMap(), Consumed.with(Serdes.String(), JsonSerdes.ProcessedMapGeoJson()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreProcessedMapName()),
+ Serdes.String(), JsonSerdes.ProcessedMapGeoJson()));
+
+ KStream> deduplicatedStream = inputStream.process(new ProcessedMapProcessorSupplier(props), props.getKafkaStateStoreProcessedMapName());
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedProcessedMap(), Produced.with(Serdes.String(), JsonSerdes.ProcessedMapGeoJson()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Processed Map deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Processed Map deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+
+
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapWktDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapWktDeduplicatorTopology.java
new file mode 100644
index 0000000..872e66f
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedMapWktDeduplicatorTopology.java
@@ -0,0 +1,93 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.ProcessedMapWktProcessorSupplier;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.util.Properties;
+
+public class ProcessedMapWktDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(MapDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ String inputTopic;
+ String outputTopic;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DeduplicatorProperties props;
+
+ public ProcessedMapWktDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties){
+ this.props = props;
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ }
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Processed Map WKT Deduplicator Topology");
+ streams.start();
+ }
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream> inputStream = builder.stream(props.getKafkaTopicProcessedMapWKT(), Consumed.with(Serdes.String(), JsonSerdes.ProcessedMapWKT()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreProcessedMapWKTName()),
+ Serdes.String(), JsonSerdes.ProcessedMapWKT()));
+
+ KStream> deduplicatedStream = inputStream.process(new ProcessedMapWktProcessorSupplier(props), props.getKafkaStateStoreProcessedMapWKTName());
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedProcessedMapWKT(), Produced.with(Serdes.String(), JsonSerdes.ProcessedMapWKT()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Processed Map deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Processed Map deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+
+
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedSpatDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedSpatDeduplicatorTopology.java
new file mode 100644
index 0000000..6f55329
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/ProcessedSpatDeduplicatorTopology.java
@@ -0,0 +1,96 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.ProcessedSpatProcessorSupplier;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.ProcessedSpat;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.time.format.DateTimeFormatter;
+import java.util.Properties;
+
+public class ProcessedSpatDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(ProcessedSpatDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ String inputTopic;
+ String outputTopic;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ DeduplicatorProperties props;
+
+
+ public ProcessedSpatDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties){
+ this.props = props;
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ }
+
+
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null) streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null) streams.setStateListener(stateListener);
+ logger.info("Starting Map Deduplicator Topology");
+ streams.start();
+ }
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream inputStream = builder.stream(props.getKafkaTopicProcessedSpat(), Consumed.with(Serdes.String(), JsonSerdes.ProcessedSpat()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreProcessedSpatName()),
+ Serdes.String(), JsonSerdes.ProcessedSpat()));
+
+ KStream deduplicatedStream = inputStream.process(new ProcessedSpatProcessorSupplier(props), props.getKafkaStateStoreProcessedSpatName());
+
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedProcessedSpat(), Produced.with(Serdes.String(), JsonSerdes.ProcessedSpat()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Processed SPaT deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Processed SPaT deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+}
diff --git a/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/TimDeduplicatorTopology.java b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/TimDeduplicatorTopology.java
new file mode 100644
index 0000000..f128da9
--- /dev/null
+++ b/jpo-deduplicator/src/main/java/us/dot/its/jpo/deduplicator/deduplicator/topologies/TimDeduplicatorTopology.java
@@ -0,0 +1,126 @@
+package us.dot.its.jpo.deduplicator.deduplicator.topologies;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KafkaStreams;
+import org.apache.kafka.streams.StreamsBuilder;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.KafkaStreams.StateListener;
+import org.apache.kafka.streams.errors.StreamsUncaughtExceptionHandler;
+
+import us.dot.its.jpo.geojsonconverter.DateJsonMapper;
+import us.dot.its.jpo.ode.model.OdeTimData;
+import us.dot.its.jpo.ode.model.OdeTimMetadata;
+import us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation;
+
+import org.apache.kafka.streams.kstream.*;
+import org.apache.kafka.streams.state.Stores;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import java.time.format.DateTimeFormatter;
+import java.util.Properties;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.processors.suppliers.OdeTimJsonProcessorSupplier;
+import us.dot.its.jpo.deduplicator.deduplicator.serialization.JsonSerdes;
+
+
+public class TimDeduplicatorTopology {
+
+ private static final Logger logger = LoggerFactory.getLogger(TimDeduplicatorTopology.class);
+
+ Topology topology;
+ KafkaStreams streams;
+ Properties streamsProperties;
+ ObjectMapper objectMapper;
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
+ DeduplicatorProperties props;
+
+ public TimDeduplicatorTopology(DeduplicatorProperties props, Properties streamsProperties) {
+ this.props = props;
+ this.streamsProperties = streamsProperties;
+ this.objectMapper = DateJsonMapper.getInstance();
+ }
+
+ public void start() {
+ if (streams != null && streams.state().isRunningOrRebalancing()) {
+ throw new IllegalStateException("Start called while streams is already running.");
+ }
+ Topology topology = buildTopology();
+ streams = new KafkaStreams(topology, streamsProperties);
+ if (exceptionHandler != null)
+ streams.setUncaughtExceptionHandler(exceptionHandler);
+ if (stateListener != null)
+ streams.setStateListener(stateListener);
+ logger.info("Starting Tim Deduplicator Topology");
+ streams.start();
+ }
+
+ public JsonNode genJsonNode() {
+ return objectMapper.createObjectNode();
+ }
+
+
+
+ public Topology buildTopology() {
+ StreamsBuilder builder = new StreamsBuilder();
+
+ KStream inputStream = builder.stream(props.getKafkaTopicOdeTimJson(),
+ Consumed.with(Serdes.String(), JsonSerdes.OdeTim()));
+
+ builder.addStateStore(Stores.keyValueStoreBuilder(Stores.persistentKeyValueStore(props.getKafkaStateStoreOdeTimJsonName()),
+ Serdes.String(), JsonSerdes.OdeTim()));
+
+ KStream timRekeyedStream = inputStream.selectKey((key, value) -> {
+ try {
+
+ TravelerInformation travellerInformation = (TravelerInformation)value.getPayload().getData();
+
+
+ String rsuIP = ((OdeTimMetadata)value.getMetadata()).getOriginIp();
+ // String packetId = ((OdeTimPayload)value.getPayload()).getData();// .get("packetID").asText();
+ String packetId = travellerInformation.getPacketID().toString();
+ int msgCnt = travellerInformation.getMsgCnt().intValue();
+
+ String newKey = rsuIP + "_" + packetId + "_" + msgCnt;
+ return newKey;
+ } catch (Exception e) {
+ logger.error(e.toString());
+ return "";
+ }
+ }).repartition(Repartitioned.with(Serdes.String(), JsonSerdes.OdeTim()));
+
+ KStream deduplicatedStream = timRekeyedStream.process(new OdeTimJsonProcessorSupplier(props), props.getKafkaStateStoreOdeTimJsonName());
+
+ deduplicatedStream.to(props.getKafkaTopicDeduplicatedOdeTimJson(), Produced.with(Serdes.String(), JsonSerdes.OdeTim()));
+
+ return builder.build();
+
+ }
+
+ public void stop() {
+ logger.info("Stopping Tim deduplicator Socket Broadcast Topology.");
+ if (streams != null) {
+ streams.close();
+ streams.cleanUp();
+ streams = null;
+ }
+ logger.info("Stopped Tim deduplicator Socket Broadcast Topology.");
+ }
+
+ StateListener stateListener;
+
+ public void registerStateListener(StateListener stateListener) {
+ this.stateListener = stateListener;
+ }
+
+ StreamsUncaughtExceptionHandler exceptionHandler;
+
+ public void registerUncaughtExceptionHandler(StreamsUncaughtExceptionHandler exceptionHandler) {
+ this.exceptionHandler = exceptionHandler;
+ }
+
+}
diff --git a/jpo-deduplicator/src/main/resources/application.yaml b/jpo-deduplicator/src/main/resources/application.yaml
new file mode 100644
index 0000000..7e01e98
--- /dev/null
+++ b/jpo-deduplicator/src/main/resources/application.yaml
@@ -0,0 +1,96 @@
+#General Properties
+#==================
+groupId: ^project.groupId^
+artifactId: ^project.artifactId^
+version: ^project.version^
+server.port: 8085
+
+# Kafka properties
+spring.kafka.bootstrap-servers: ${KAFKA_BOOTSTRAP_SERVERS:localhost:9092}
+logging.level.org.apache.kafka: INFO
+logging.level: INFO
+log4j.logger.kafka: OFF
+log4j.logger.org.apache.kafka: OFF
+
+
+
+# Processed Map Configuration
+kafkaTopicProcessedMap: topic.ProcessedMap
+kafkaTopicDeduplicatedProcessedMap: topic.DeduplicatedProcessedMap
+enableProcessedMapDeduplication: ${ENABLE_PROCESSED_MAP_DEDUPLICATION:true}
+
+# Processed Map WKT Configuration
+kafkaTopicProcessedMapWKT: topic.ProcessedMapWKT
+kafkaTopicDeduplicatedProcessedMapWKT: topic.DeduplicatedProcessedMapWKT
+enableProcessedMapWktDeduplication: ${ENABLE_PROCESSED_MAP_WKT_DEDUPLICATION:true}
+
+# Ode Map Json Configuration
+kafkaTopicOdeMapJson: topic.OdeMapJson
+kafkaTopicDeduplicatedOdeMapJson: topic.DeduplicatedOdeMapJson
+enableOdeMapDeduplication: ${ENABLE_ODE_MAP_DEDUPLICATION:true}
+
+# Ode Tim Json Configuration
+kafkaTopicOdeTimJson: topic.OdeTimJson
+kafkaTopicDeduplicatedOdeTimJson: topic.DeduplicatedOdeTimJson
+enableOdeTimDeduplication: ${ENABLE_ODE_TIM_DEDUPLICATION:true}
+
+# Ode Raw Encoded Tim Json Configuration
+kafkaTopicOdeRawEncodedTimJson: topic.OdeRawEncodedTIMJson
+kafkaTopicDeduplicatedOdeRawEncodedTimJson: topic.DeduplicatedOdeRawEncodedTIMJson
+enableOdeRawEncodedTimDeduplication: ${ENABLE_ODE_RAW_ENCODED_TIM_DEDUPLICATION:true}
+
+# Ode Bsm Json Configuration
+kafkaTopicOdeBsmJson: topic.OdeBsmJson
+kafkaTopicDeduplicatedOdeBsmJson: topic.DeduplicatedOdeBsmJson
+enableOdeBsmDeduplication: ${ENABLE_ODE_BSM_DEDUPLICATION:true}
+odeBsmMaximumTimeDelta: 10000 # Milliseconds
+odeBsmMaximumPositionDelta: 1 # Meter
+odeBsmAlwaysIncludeAtSpeed: 1 # Meter / Second
+
+# Processed Map Configuration
+kafkaTopicProcessedSpat: topic.ProcessedSpat
+kafkaTopicDeduplicatedProcessedSpat: topic.DeduplicatedProcessedSpat
+enableProcessedSpatDeduplication: ${ENABLE_PROCESSED_SPAT_DEDUPLICATION:true}
+
+
+# Amount of time to wait to try and increase batching
+kafka.linger_ms: 50
+
+# Custom kafka properties
+kafka.topics:
+ autoCreateTopics: true # Override auto-create in test properties
+ numPartitions: 1
+ numReplicas: 1
+ createTopics:
+ - name: ${kafkaTopicProcessedMap}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicDeduplicatedProcessedMap}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicProcessedMapWKT}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicDeduplicatedProcessedMapWKT}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicOdeMapJson}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicDeduplicatedOdeMapJson}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicOdeTimJson}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicDeduplicatedOdeTimJson}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicProcessedSpat}
+ cleanupPolicy: delete
+ retentionMs: 300000
+ - name: ${kafkaTopicDeduplicatedProcessedSpat}
+ cleanupPolicy: delete
+ retentionMs: 300000
+
+
\ No newline at end of file
diff --git a/jpo-deduplicator/src/main/resources/logback.xml b/jpo-deduplicator/src/main/resources/logback.xml
new file mode 100644
index 0000000..860df15
--- /dev/null
+++ b/jpo-deduplicator/src/main/resources/logback.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ %date{"yyyy-MM-dd HH:mm:ss", UTC} [%thread] %-5level %logger{0} - %msg %n
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jpo-deduplicator/src/test/java/deduplicator/BsmDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/BsmDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..adb1e95
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/BsmDeduplicatorTopologyTest.java
@@ -0,0 +1,116 @@
+package deduplicator;
+
+
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import us.dot.its.jpo.conflictmonitor.monitor.serialization.JsonSerdes;
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.BsmDeduplicatorTopology;
+import us.dot.its.jpo.ode.model.OdeBsmData;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+
+public class BsmDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.OdeBsmJson";
+ String outputTopic = "topic.DeduplicatedOdeBsmJson";
+ ObjectMapper objectMapper;
+
+ String inputBsm1 = "{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"9bc470d1-babe-415b-8c5a-4cd4a9403350\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-01-31T23:14:24.693Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"coreData\":{\"msgCnt\":37,\"id\":\"31325433\",\"secMark\":25399,\"position\":{\"latitude\":40.5659938,\"longitude\":-105.0317754,\"elevation\":1440.9},\"accelSet\":{\"accelLat\":0.00,\"accelLong\":0.27,\"accelVert\":0.00,\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":9.30,\"semiMinor\":12.05},\"transmission\":\"UNAVAILABLE\",\"speed\":0.28,\"heading\":313.2500,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":190,\"length\":570}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":-0.6,\"latOffset\":-0.0000113,\"lonOffset\":0.0000181,\"timeOffset\":1.90},{\"elevationOffset\":-2.3,\"latOffset\":-0.0000310,\"lonOffset\":0.0000472,\"timeOffset\":6.10},{\"elevationOffset\":-1.4,\"latOffset\":-0.0000103,\"lonOffset\":0.0000636,\"timeOffset\":15.70},{\"elevationOffset\":-1.3,\"latOffset\":-0.0000052,\"lonOffset\":0.0000615,\"timeOffset\":18.70},{\"elevationOffset\":-1.7,\"latOffset\":0.0000614,\"lonOffset\":0.0001150,\"timeOffset\":25.89},{\"elevationOffset\":0.7,\"latOffset\":0.0001878,\"lonOffset\":0.0002503,\"timeOffset\":39.59},{\"elevationOffset\":3.1,\"latOffset\":0.0002333,\"lonOffset\":0.0002816,\"timeOffset\":45.39},{\"elevationOffset\":3.9,\"latOffset\":0.0002187,\"lonOffset\":0.0002952,\"timeOffset\":49.59},{\"elevationOffset\":4.6,\"latOffset\":0.0001976,\"lonOffset\":0.0002721,\"timeOffset\":56.99},{\"elevationOffset\":8.4,\"latOffset\":0.0001891,\"lonOffset\":0.0003655,\"timeOffset\":60.50},{\"elevationOffset\":13.7,\"latOffset\":0.0002022,\"lonOffset\":0.0004886,\"timeOffset\":63.49},{\"elevationOffset\":14.4,\"latOffset\":0.0001973,\"lonOffset\":0.0004861,\"timeOffset\":67.60},{\"elevationOffset\":14.4,\"latOffset\":0.0001795,\"lonOffset\":0.0004815,\"timeOffset\":72.70},{\"elevationOffset\":13.5,\"latOffset\":0.0001710,\"lonOffset\":0.0004749,\"timeOffset\":75.70},{\"elevationOffset\":12.1,\"latOffset\":0.0001609,\"lonOffset\":0.0004566,\"timeOffset\":78.80}]},\"pathPrediction\":{\"confidence\":0.0,\"radiusOfCurve\":0.0}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":1.90},\"doNotUse2\":{}}}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\"}}";
+
+ // Same as BSM 1 - No Message should be generated
+ String inputBsm2 = "{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"9bc470d1-babe-415b-8c5a-4cd4a9403350\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-01-31T23:14:24.793Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"coreData\":{\"msgCnt\":37,\"id\":\"31325433\",\"secMark\":25399,\"position\":{\"latitude\":40.5659938,\"longitude\":-105.0317754,\"elevation\":1440.9},\"accelSet\":{\"accelLat\":0.00,\"accelLong\":0.27,\"accelVert\":0.00,\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":9.30,\"semiMinor\":12.05},\"transmission\":\"UNAVAILABLE\",\"speed\":0.28,\"heading\":313.2500,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":190,\"length\":570}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":-0.6,\"latOffset\":-0.0000113,\"lonOffset\":0.0000181,\"timeOffset\":1.90},{\"elevationOffset\":-2.3,\"latOffset\":-0.0000310,\"lonOffset\":0.0000472,\"timeOffset\":6.10},{\"elevationOffset\":-1.4,\"latOffset\":-0.0000103,\"lonOffset\":0.0000636,\"timeOffset\":15.70},{\"elevationOffset\":-1.3,\"latOffset\":-0.0000052,\"lonOffset\":0.0000615,\"timeOffset\":18.70},{\"elevationOffset\":-1.7,\"latOffset\":0.0000614,\"lonOffset\":0.0001150,\"timeOffset\":25.89},{\"elevationOffset\":0.7,\"latOffset\":0.0001878,\"lonOffset\":0.0002503,\"timeOffset\":39.59},{\"elevationOffset\":3.1,\"latOffset\":0.0002333,\"lonOffset\":0.0002816,\"timeOffset\":45.39},{\"elevationOffset\":3.9,\"latOffset\":0.0002187,\"lonOffset\":0.0002952,\"timeOffset\":49.59},{\"elevationOffset\":4.6,\"latOffset\":0.0001976,\"lonOffset\":0.0002721,\"timeOffset\":56.99},{\"elevationOffset\":8.4,\"latOffset\":0.0001891,\"lonOffset\":0.0003655,\"timeOffset\":60.50},{\"elevationOffset\":13.7,\"latOffset\":0.0002022,\"lonOffset\":0.0004886,\"timeOffset\":63.49},{\"elevationOffset\":14.4,\"latOffset\":0.0001973,\"lonOffset\":0.0004861,\"timeOffset\":67.60},{\"elevationOffset\":14.4,\"latOffset\":0.0001795,\"lonOffset\":0.0004815,\"timeOffset\":72.70},{\"elevationOffset\":13.5,\"latOffset\":0.0001710,\"lonOffset\":0.0004749,\"timeOffset\":75.70},{\"elevationOffset\":12.1,\"latOffset\":0.0001609,\"lonOffset\":0.0004566,\"timeOffset\":78.80}]},\"pathPrediction\":{\"confidence\":0.0,\"radiusOfCurve\":0.0}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":1.90},\"doNotUse2\":{}}}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\"}}";
+
+ // Increase Time from Bsm 1
+ String inputBsm3 = "{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"9bc470d1-babe-415b-8c5a-4cd4a9403350\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-01-31T23:14:34.793Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"coreData\":{\"msgCnt\":37,\"id\":\"31325433\",\"secMark\":25399,\"position\":{\"latitude\":40.5659938,\"longitude\":-105.0317754,\"elevation\":1440.9},\"accelSet\":{\"accelLat\":0.00,\"accelLong\":0.27,\"accelVert\":0.00,\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":9.30,\"semiMinor\":12.05},\"transmission\":\"UNAVAILABLE\",\"speed\":0.28,\"heading\":313.2500,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":190,\"length\":570}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":-0.6,\"latOffset\":-0.0000113,\"lonOffset\":0.0000181,\"timeOffset\":1.90},{\"elevationOffset\":-2.3,\"latOffset\":-0.0000310,\"lonOffset\":0.0000472,\"timeOffset\":6.10},{\"elevationOffset\":-1.4,\"latOffset\":-0.0000103,\"lonOffset\":0.0000636,\"timeOffset\":15.70},{\"elevationOffset\":-1.3,\"latOffset\":-0.0000052,\"lonOffset\":0.0000615,\"timeOffset\":18.70},{\"elevationOffset\":-1.7,\"latOffset\":0.0000614,\"lonOffset\":0.0001150,\"timeOffset\":25.89},{\"elevationOffset\":0.7,\"latOffset\":0.0001878,\"lonOffset\":0.0002503,\"timeOffset\":39.59},{\"elevationOffset\":3.1,\"latOffset\":0.0002333,\"lonOffset\":0.0002816,\"timeOffset\":45.39},{\"elevationOffset\":3.9,\"latOffset\":0.0002187,\"lonOffset\":0.0002952,\"timeOffset\":49.59},{\"elevationOffset\":4.6,\"latOffset\":0.0001976,\"lonOffset\":0.0002721,\"timeOffset\":56.99},{\"elevationOffset\":8.4,\"latOffset\":0.0001891,\"lonOffset\":0.0003655,\"timeOffset\":60.50},{\"elevationOffset\":13.7,\"latOffset\":0.0002022,\"lonOffset\":0.0004886,\"timeOffset\":63.49},{\"elevationOffset\":14.4,\"latOffset\":0.0001973,\"lonOffset\":0.0004861,\"timeOffset\":67.60},{\"elevationOffset\":14.4,\"latOffset\":0.0001795,\"lonOffset\":0.0004815,\"timeOffset\":72.70},{\"elevationOffset\":13.5,\"latOffset\":0.0001710,\"lonOffset\":0.0004749,\"timeOffset\":75.70},{\"elevationOffset\":12.1,\"latOffset\":0.0001609,\"lonOffset\":0.0004566,\"timeOffset\":78.80}]},\"pathPrediction\":{\"confidence\":0.0,\"radiusOfCurve\":0.0}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":1.90},\"doNotUse2\":{}}}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\"}}";
+
+ // Vehicle Speed not 0
+ String inputBsm4 = "{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"9bc470d1-babe-415b-8c5a-4cd4a9403350\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-01-31T23:14:34.893Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"coreData\":{\"msgCnt\":37,\"id\":\"31325433\",\"secMark\":25399,\"position\":{\"latitude\":40.5659938,\"longitude\":-105.0317754,\"elevation\":1440.9},\"accelSet\":{\"accelLat\":0.00,\"accelLong\":0.27,\"accelVert\":0.00,\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":9.30,\"semiMinor\":12.05},\"transmission\":\"UNAVAILABLE\",\"speed\":5,\"heading\":313.2500,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":190,\"length\":570}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":-0.6,\"latOffset\":-0.0000113,\"lonOffset\":0.0000181,\"timeOffset\":1.90},{\"elevationOffset\":-2.3,\"latOffset\":-0.0000310,\"lonOffset\":0.0000472,\"timeOffset\":6.10},{\"elevationOffset\":-1.4,\"latOffset\":-0.0000103,\"lonOffset\":0.0000636,\"timeOffset\":15.70},{\"elevationOffset\":-1.3,\"latOffset\":-0.0000052,\"lonOffset\":0.0000615,\"timeOffset\":18.70},{\"elevationOffset\":-1.7,\"latOffset\":0.0000614,\"lonOffset\":0.0001150,\"timeOffset\":25.89},{\"elevationOffset\":0.7,\"latOffset\":0.0001878,\"lonOffset\":0.0002503,\"timeOffset\":39.59},{\"elevationOffset\":3.1,\"latOffset\":0.0002333,\"lonOffset\":0.0002816,\"timeOffset\":45.39},{\"elevationOffset\":3.9,\"latOffset\":0.0002187,\"lonOffset\":0.0002952,\"timeOffset\":49.59},{\"elevationOffset\":4.6,\"latOffset\":0.0001976,\"lonOffset\":0.0002721,\"timeOffset\":56.99},{\"elevationOffset\":8.4,\"latOffset\":0.0001891,\"lonOffset\":0.0003655,\"timeOffset\":60.50},{\"elevationOffset\":13.7,\"latOffset\":0.0002022,\"lonOffset\":0.0004886,\"timeOffset\":63.49},{\"elevationOffset\":14.4,\"latOffset\":0.0001973,\"lonOffset\":0.0004861,\"timeOffset\":67.60},{\"elevationOffset\":14.4,\"latOffset\":0.0001795,\"lonOffset\":0.0004815,\"timeOffset\":72.70},{\"elevationOffset\":13.5,\"latOffset\":0.0001710,\"lonOffset\":0.0004749,\"timeOffset\":75.70},{\"elevationOffset\":12.1,\"latOffset\":0.0001609,\"lonOffset\":0.0004566,\"timeOffset\":78.80}]},\"pathPrediction\":{\"confidence\":0.0,\"radiusOfCurve\":0.0}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":1.90},\"doNotUse2\":{}}}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\"}}";
+
+ // Vehicle Position has changed
+ String inputBsm5 = "{\"metadata\":{\"bsmSource\":\"EV\",\"logFileName\":\"\",\"recordType\":\"bsmTx\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"locationData\":{\"latitude\":\"unavailable\",\"longitude\":\"unavailable\",\"elevation\":\"unavailable\",\"speed\":\"unavailable\",\"heading\":\"unavailable\"},\"rxSource\":\"RSU\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeBsmPayload\",\"serialId\":{\"streamId\":\"9bc470d1-babe-415b-8c5a-4cd4a9403350\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-01-31T23:14:34.993Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"OBU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001480B8494C4C950CD8CDE6E9651116579F22A424DD78FFFFF00761E4FD7EB7D07F7FFF80005F11D1020214C1C0FFC7C016AFF4017A0FF65403B0FD204C20FFCCC04F8FE40C420FFE6404CEFE60E9A10133408FCFDE1438103AB4138F00E1EEC1048EC160103E237410445C171104E26BC103DC4154305C2C84103B1C1C8F0A82F42103F34262D1123198103DAC25FB12034CE10381C259F12038CA103574251B10E3B2210324C23AD0F23D8EFFFE0000209340D10000004264BF00\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"coreData\":{\"msgCnt\":37,\"id\":\"31325433\",\"secMark\":25399,\"position\":{\"latitude\":40.6659938,\"longitude\":-105.0317754,\"elevation\":1440.9},\"accelSet\":{\"accelLat\":0.00,\"accelLong\":0.27,\"accelVert\":0.00,\"accelYaw\":0.00},\"accuracy\":{\"semiMajor\":9.30,\"semiMinor\":12.05},\"transmission\":\"UNAVAILABLE\",\"speed\":0.28,\"heading\":313.2500,\"brakes\":{\"wheelBrakes\":{\"leftFront\":false,\"rightFront\":false,\"unavailable\":true,\"leftRear\":false,\"rightRear\":false},\"traction\":\"unavailable\",\"abs\":\"unavailable\",\"scs\":\"unavailable\",\"brakeBoost\":\"unavailable\",\"auxBrakes\":\"unavailable\"},\"size\":{\"width\":190,\"length\":570}},\"partII\":[{\"id\":\"VehicleSafetyExtensions\",\"value\":{\"pathHistory\":{\"crumbData\":[{\"elevationOffset\":-0.6,\"latOffset\":-0.0000113,\"lonOffset\":0.0000181,\"timeOffset\":1.90},{\"elevationOffset\":-2.3,\"latOffset\":-0.0000310,\"lonOffset\":0.0000472,\"timeOffset\":6.10},{\"elevationOffset\":-1.4,\"latOffset\":-0.0000103,\"lonOffset\":0.0000636,\"timeOffset\":15.70},{\"elevationOffset\":-1.3,\"latOffset\":-0.0000052,\"lonOffset\":0.0000615,\"timeOffset\":18.70},{\"elevationOffset\":-1.7,\"latOffset\":0.0000614,\"lonOffset\":0.0001150,\"timeOffset\":25.89},{\"elevationOffset\":0.7,\"latOffset\":0.0001878,\"lonOffset\":0.0002503,\"timeOffset\":39.59},{\"elevationOffset\":3.1,\"latOffset\":0.0002333,\"lonOffset\":0.0002816,\"timeOffset\":45.39},{\"elevationOffset\":3.9,\"latOffset\":0.0002187,\"lonOffset\":0.0002952,\"timeOffset\":49.59},{\"elevationOffset\":4.6,\"latOffset\":0.0001976,\"lonOffset\":0.0002721,\"timeOffset\":56.99},{\"elevationOffset\":8.4,\"latOffset\":0.0001891,\"lonOffset\":0.0003655,\"timeOffset\":60.50},{\"elevationOffset\":13.7,\"latOffset\":0.0002022,\"lonOffset\":0.0004886,\"timeOffset\":63.49},{\"elevationOffset\":14.4,\"latOffset\":0.0001973,\"lonOffset\":0.0004861,\"timeOffset\":67.60},{\"elevationOffset\":14.4,\"latOffset\":0.0001795,\"lonOffset\":0.0004815,\"timeOffset\":72.70},{\"elevationOffset\":13.5,\"latOffset\":0.0001710,\"lonOffset\":0.0004749,\"timeOffset\":75.70},{\"elevationOffset\":12.1,\"latOffset\":0.0001609,\"lonOffset\":0.0004566,\"timeOffset\":78.80}]},\"pathPrediction\":{\"confidence\":0.0,\"radiusOfCurve\":0.0}}},{\"id\":\"SupplementalVehicleExtensions\",\"value\":{\"classDetails\":{\"fuelType\":\"unknownFuel\",\"hpmsType\":\"none\",\"keyType\":0,\"role\":\"basicVehicle\"},\"vehicleData\":{\"height\":1.90},\"doNotUse2\":{}}}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.J2735Bsm\"}}";
+
+
+ @Autowired
+ DeduplicatorProperties props;
+
+
+
+ @Test
+ public void testTopology() {
+
+
+
+
+
+ props = new DeduplicatorProperties();
+ props.setAlwaysIncludeAtSpeed(1);
+ props.setenableOdeBsmDeduplication(true);
+ props.setMaximumPositionDelta(1);
+ props.setMaximumTimeDelta(10000);
+ props.setkafkaTopicOdeBsmJson(inputTopic);
+ props.setkafkaTopicDeduplicatedOdeBsmJson(outputTopic);
+
+ BsmDeduplicatorTopology bsmDeduplicatorTopology = new BsmDeduplicatorTopology(props);
+ Topology topology = bsmDeduplicatorTopology.buildTopology();
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputOdeBsmData = driver.createInputTopic(
+ inputTopic,
+ Serdes.Void().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic outputOdeBsmData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ JsonSerdes.OdeBsm().deserializer());
+
+ inputOdeBsmData.pipeInput(null, inputBsm1);
+ inputOdeBsmData.pipeInput(null, inputBsm2);
+ inputOdeBsmData.pipeInput(null, inputBsm3);
+ inputOdeBsmData.pipeInput(null, inputBsm4);
+ inputOdeBsmData.pipeInput(null, inputBsm5);
+
+ List> bsmDeduplicationResults = outputOdeBsmData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(4, bsmDeduplicationResults.size());
+
+ objectMapper = new ObjectMapper();
+ OdeBsmData bsm1 = objectMapper.readValue(inputBsm1, OdeBsmData.class);
+ OdeBsmData bsm3 = objectMapper.readValue(inputBsm3, OdeBsmData.class);
+ OdeBsmData bsm4 = objectMapper.readValue(inputBsm4, OdeBsmData.class);
+ OdeBsmData bsm5 = objectMapper.readValue(inputBsm5, OdeBsmData.class);
+
+
+ assertEquals(bsm1.getMetadata().getOdeReceivedAt(), bsmDeduplicationResults.get(0).value.getMetadata().getOdeReceivedAt());
+ assertEquals(bsm3.getMetadata().getOdeReceivedAt(), bsmDeduplicationResults.get(1).value.getMetadata().getOdeReceivedAt());
+ assertEquals(bsm4.getMetadata().getOdeReceivedAt(), bsmDeduplicationResults.get(2).value.getMetadata().getOdeReceivedAt());
+ assertEquals(bsm5.getMetadata().getOdeReceivedAt(), bsmDeduplicationResults.get(3).value.getMetadata().getOdeReceivedAt());
+
+ } catch (JsonMappingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (JsonProcessingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/java/deduplicator/MapDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/MapDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..54aa14a
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/MapDeduplicatorTopologyTest.java
@@ -0,0 +1,115 @@
+package deduplicator;
+
+
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.MapDeduplicatorTopology;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import us.dot.its.jpo.ode.model.OdeMapData;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+
+public class MapDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.OdeMapJson";
+ String outputTopic = "topic.DeduplicatedOdeMapJson";
+ ObjectMapper objectMapper;
+
+ String inputMap1 = "";
+ String inputMap2 = "";
+ String inputMap3 = "";
+ String inputMap4 = "";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+ @Before
+ public void setup() throws IOException {
+ // Load test files from resources
+
+ // Reference MAP
+ inputMap1 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/map/sample.map-reference.json")));
+
+ // Duplicate of Number 1
+ inputMap2 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/map/sample.map-reference.json")));
+
+ // A different Message entirely
+ inputMap3 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/map/sample.map-different.json")));
+
+ // Message 1 but 1 hour later
+ inputMap4 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/map/sample.map-reference-1-hour-later.json")));
+ }
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicOdeMapJson(inputTopic);
+ props.setKafkaTopicDeduplicatedOdeMapJson(outputTopic);
+
+ MapDeduplicatorTopology mapDeduplicatorTopology = new MapDeduplicatorTopology(props, null);
+
+ Topology topology = mapDeduplicatorTopology.buildTopology();
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputOdeMapData = driver.createInputTopic(
+ inputTopic,
+ Serdes.Void().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic outputOdeMapData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ JsonSerdes.OdeMap().deserializer());
+
+ inputOdeMapData.pipeInput(null, inputMap1);
+ inputOdeMapData.pipeInput(null, inputMap2);
+ inputOdeMapData.pipeInput(null, inputMap3);
+ inputOdeMapData.pipeInput(null, inputMap4);
+
+ List> mapDeduplicationResults = outputOdeMapData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(3, mapDeduplicationResults.size());
+
+ objectMapper = new ObjectMapper();
+ OdeMapData map1 = objectMapper.readValue(inputMap1, OdeMapData.class);
+ OdeMapData map3 = objectMapper.readValue(inputMap3, OdeMapData.class);
+ OdeMapData map4 = objectMapper.readValue(inputMap4, OdeMapData.class);
+
+
+ assertEquals(map1.getMetadata().getOdeReceivedAt(), mapDeduplicationResults.get(0).value.getMetadata().getOdeReceivedAt());
+ assertEquals(map3.getMetadata().getOdeReceivedAt(), mapDeduplicationResults.get(1).value.getMetadata().getOdeReceivedAt());
+ assertEquals(map4.getMetadata().getOdeReceivedAt(), mapDeduplicationResults.get(2).value.getMetadata().getOdeReceivedAt());
+
+ } catch (JsonMappingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (JsonProcessingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/java/deduplicator/OdeRawEncodedTimDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/OdeRawEncodedTimDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..4b618d9
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/OdeRawEncodedTimDeduplicatorTopologyTest.java
@@ -0,0 +1,89 @@
+package deduplicator;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.OdeRawEncodedTimDeduplicatorTopology;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+
+public class OdeRawEncodedTimDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.OdeRawEncodedTIMJson";
+ String outputTopic = "topic.DeduplicatedOdeRawEncodedTIMJson";
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // Original Message
+ String inputTim1 = "{ \"metadata\": { \"securityResultCode\": \"success\", \"recordGeneratedBy\": \"RSU\", \"schemaVersion\": 6, \"payloadType\": \"us.dot.its.jpo.ode.model.OdeAsn1Payload\", \"serialId\": { \"recordId\": 0, \"serialNumber\": 0, \"streamId\": \"5f470323-7770-4810-b225-8c45aa672103\", \"bundleSize\": 1, \"bundleId\": 0 }, \"sanitized\": false, \"recordType\": \"timMsg\", \"maxDurationTime\": 0, \"odeReceivedAt\": \"2024-07-22T23:23:29.553Z\", \"originIp\": \"10.16.28.53\" }, \"payload\": { \"data\": { \"bytes\": \"001F63701409FF38D05CD47AF567A4570F775D9B0301C269D16DD9656F9637FFF93F421D3B001EA007F99937E1CF5AD1BB0BF4A9D5BEC5BB25CC5B2E64E173162DA00000000269D16DD9656F9631388C100021000EBF7272441F8CFDED60004008027BBAECD8A1A81EF1C153853DD08B394DDCE85F7F4F2222BE087C98000801004F775D9B002F378A81FD1358540F893502C0B711D815FF7883E0A9AACF804536FC9E2A39A67D4289155859ABA8ACBD4997855D345BA429991568E1CA702BA1D8ADFF4805456C0A46862B7F41BE614A122DFB8B0FA019FC52FC8AFF62A7DA3D3F1C9A00BC220AA6B0DC20571A23C142A8C0368F14D181D9B8E2FA859714531606FF8197DC2D81469C97540A33D8D25850D7CA7E82916C1F82142D3A8A20A4884311C320C8EB2290AD1BAC0C84856E8A1B1D760C51BE458B8189591FF0C64E68D0004008027BBAECD8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" }, \"dataType\": \"us.dot.its.jpo.ode.model.OdeHexByteArray\" }}";
+
+ // Shifted Forward .1 seconds - Should be deduplicated
+ String inputTim2 = "{ \"metadata\": { \"securityResultCode\": \"success\", \"recordGeneratedBy\": \"RSU\", \"schemaVersion\": 6, \"payloadType\": \"us.dot.its.jpo.ode.model.OdeAsn1Payload\", \"serialId\": { \"recordId\": 0, \"serialNumber\": 0, \"streamId\": \"5f470323-7770-4810-b225-8c45aa672103\", \"bundleSize\": 1, \"bundleId\": 0 }, \"sanitized\": false, \"recordType\": \"timMsg\", \"maxDurationTime\": 0, \"odeReceivedAt\": \"2024-07-22T23:23:29.653Z\", \"originIp\": \"10.16.28.53\" }, \"payload\": { \"data\": { \"bytes\": \"001F63701409FF38D05CD47AF567A4570F775D9B0301C269D16DD9656F9637FFF93F421D3B001EA007F99937E1CF5AD1BB0BF4A9D5BEC5BB25CC5B2E64E173162DA00000000269D16DD9656F9631388C100021000EBF7272441F8CFDED60004008027BBAECD8A1A81EF1C153853DD08B394DDCE85F7F4F2222BE087C98000801004F775D9B002F378A81FD1358540F893502C0B711D815FF7883E0A9AACF804536FC9E2A39A67D4289155859ABA8ACBD4997855D345BA429991568E1CA702BA1D8ADFF4805456C0A46862B7F41BE614A122DFB8B0FA019FC52FC8AFF62A7DA3D3F1C9A00BC220AA6B0DC20571A23C142A8C0368F14D181D9B8E2FA859714531606FF8197DC2D81469C97540A33D8D25850D7CA7E82916C1F82142D3A8A20A4884311C320C8EB2290AD1BAC0C84856E8A1B1D760C51BE458B8189591FF0C64E68D0004008027BBAECD8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" }, \"dataType\": \"us.dot.its.jpo.ode.model.OdeHexByteArray\" }}";
+
+ // Shifted Forward 1 hour Should be allowed to pass through
+ String inputTim3 = "{ \"metadata\": { \"securityResultCode\": \"success\", \"recordGeneratedBy\": \"RSU\", \"schemaVersion\": 6, \"payloadType\": \"us.dot.its.jpo.ode.model.OdeAsn1Payload\", \"serialId\": { \"recordId\": 0, \"serialNumber\": 0, \"streamId\": \"5f470323-7770-4810-b225-8c45aa672103\", \"bundleSize\": 1, \"bundleId\": 0 }, \"sanitized\": false, \"recordType\": \"timMsg\", \"maxDurationTime\": 0, \"odeReceivedAt\": \"2024-07-23T00:23:29.653Z\", \"originIp\": \"10.16.28.53\" }, \"payload\": { \"data\": { \"bytes\": \"001F63701409FF38D05CD47AF567A4570F775D9B0301C269D16DD9656F9637FFF93F421D3B001EA007F99937E1CF5AD1BB0BF4A9D5BEC5BB25CC5B2E64E173162DA00000000269D16DD9656F9631388C100021000EBF7272441F8CFDED60004008027BBAECD8A1A81EF1C153853DD08B394DDCE85F7F4F2222BE087C98000801004F775D9B002F378A81FD1358540F893502C0B711D815FF7883E0A9AACF804536FC9E2A39A67D4289155859ABA8ACBD4997855D345BA429991568E1CA702BA1D8ADFF4805456C0A46862B7F41BE614A122DFB8B0FA019FC52FC8AFF62A7DA3D3F1C9A00BC220AA6B0DC20571A23C142A8C0368F14D181D9B8E2FA859714531606FF8197DC2D81469C97540A33D8D25850D7CA7E82916C1F82142D3A8A20A4884311C320C8EB2290AD1BAC0C84856E8A1B1D760C51BE458B8189591FF0C64E68D0004008027BBAECD8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" }, \"dataType\": \"us.dot.its.jpo.ode.model.OdeHexByteArray\" }}";
+
+ // Has a different payload ID. Should be allowed through
+ String inputTim4 = "{ \"metadata\": { \"securityResultCode\": \"success\", \"recordGeneratedBy\": \"RSU\", \"schemaVersion\": 6, \"payloadType\": \"us.dot.its.jpo.ode.model.OdeAsn1Payload\", \"serialId\": { \"recordId\": 0, \"serialNumber\": 0, \"streamId\": \"5f470323-7770-4810-b225-8c45aa672103\", \"bundleSize\": 1, \"bundleId\": 0 }, \"sanitized\": false, \"recordType\": \"timMsg\", \"maxDurationTime\": 0, \"odeReceivedAt\": \"2024-07-22T23:23:29.553Z\", \"originIp\": \"10.16.28.53\" }, \"payload\": { \"data\": { \"bytes\": \"001F63701409FF38D05CD47AF567A4570F775D9B0301C269D16DD9656F9637FFF93F421D3B001EA007F99937E1CF5AD1BB0BF4A9D5BEC5BB25CC5B2E64E173162DA00000000269D16DD9656F9631388C100021000EBF7272441F8CFDED60004008027BBAECD8A1A81EF1C153853DD08B394DDCE85F7F4F2222BE087C98000801004F775D9B002F378A81FD1358540F893502C0B711D815FF7883E0A9AACF804536FC9E2A39A67D4289155859ABA8ACBD4997855D345BA429991568E1CA702BA1D8ADFF4805456C0A46862B7F41BE614A122DFB8B0FA019FC52FC8AFF62A7DA3D3F1C9A00BC220AA6B0DC20571A23C142A8C0368F14D181D9B8E2FA859714531606FF8197DC2D81469C97540A33D8D25850D7CA7E82916C1F82142D3A8A20A4884311C320C8EB2290AD1BAC0C84856E8A1B1D760C51BE458B8189591FF0C64E68D0004008027BBAECD9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\" }, \"dataType\": \"us.dot.its.jpo.ode.model.OdeHexByteArray\" }}";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicOdeRawEncodedTimJson(inputTopic);
+ props.setKafkaTopicDeduplicatedOdeRawEncodedTimJson(outputTopic);
+
+ OdeRawEncodedTimDeduplicatorTopology TimDeduplicatorTopology = new OdeRawEncodedTimDeduplicatorTopology(props, null);
+
+ Topology topology = TimDeduplicatorTopology.buildTopology();
+ objectMapper.registerModule(new JavaTimeModule());
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputTimData = driver.createInputTopic(
+ inputTopic,
+ Serdes.Void().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic outputTimData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ Serdes.String().deserializer());
+
+ inputTimData.pipeInput(null, inputTim1);
+ inputTimData.pipeInput(null, inputTim2);
+ inputTimData.pipeInput(null, inputTim3);
+ inputTimData.pipeInput(null, inputTim4);
+
+ List> timDeduplicatedResults = outputTimData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(3, timDeduplicatedResults.size());
+ inputTim1 = inputTim1.strip();
+
+ assertEquals(inputTim1.replace(" ", ""), timDeduplicatedResults.get(0).value.replace(" ", ""));
+ assertEquals(inputTim3.replace(" ", ""), timDeduplicatedResults.get(1).value.replace(" ", ""));
+ assertEquals(inputTim4.replace(" ", ""), timDeduplicatedResults.get(2).value.replace(" ", ""));
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..6868cf0
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapDeduplicatorTopologyTest.java
@@ -0,0 +1,128 @@
+package deduplicator;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedMapDeduplicatorTopology;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.LineString;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class ProcessedMapDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.ProcessedMap";
+ String outputTopic = "topic.DeduplicatedProcessedMap";
+
+
+ TypeReference> typeReference = new TypeReference<>(){};
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // Reference MAP
+ String inputProcessedMap1 = "";
+
+ // Duplicate of Number 1
+ String inputProcessedMap2 = "";
+
+ // A different Message entirely
+ String inputProcessedMap3 = "";
+
+ // Message 1 but 1 hour later
+ String inputProcessedMap4 = "";
+
+
+ String key = "{\"rsuId\":\"10.11.81.12\",\"intersectionId\":12109,\"region\":-1}";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+
+ @Before
+ public void setup() throws IOException {
+ // Load test files from resources
+
+ // Reference MAP
+ inputProcessedMap1 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map/sample.processed_map-reference.json")));
+
+ // Duplicate of Number 1
+ inputProcessedMap2 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map/sample.processed_map-reference.json")));
+
+ // A different Message entirely
+ inputProcessedMap3 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map/sample.processed_map-different.json")));
+
+ // Message 1 but 1 hour later
+ inputProcessedMap4 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map/sample.processed_map-reference-1-hour-later.json")));
+ }
+
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicProcessedMap(inputTopic);
+ props.setKafkaTopicDeduplicatedProcessedMap(outputTopic);
+
+ ProcessedMapDeduplicatorTopology processedMapDeduplicatorTopology = new ProcessedMapDeduplicatorTopology(props, null);
+
+ Topology topology = processedMapDeduplicatorTopology.buildTopology();
+ objectMapper.registerModule(new JavaTimeModule());
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputProcessedMapData = driver.createInputTopic(
+ inputTopic,
+ Serdes.String().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic> outputProcessedMapData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ JsonSerdes.ProcessedMapGeoJson().deserializer());
+
+ inputProcessedMapData.pipeInput(key, inputProcessedMap1);
+ inputProcessedMapData.pipeInput(key, inputProcessedMap2);
+ inputProcessedMapData.pipeInput(key, inputProcessedMap3);
+ inputProcessedMapData.pipeInput(key, inputProcessedMap4);
+
+ List>> mapDeduplicatorResults = outputProcessedMapData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(3, mapDeduplicatorResults.size());
+
+ ProcessedMap map1 = objectMapper.readValue(inputProcessedMap1, typeReference);
+ ProcessedMap map3 = objectMapper.readValue(inputProcessedMap3, typeReference);
+ ProcessedMap map4 = objectMapper.readValue(inputProcessedMap4, typeReference);
+
+ assertEquals(map1.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(0).value.getProperties().getOdeReceivedAt());
+ assertEquals(map3.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(1).value.getProperties().getOdeReceivedAt());
+ assertEquals(map4.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(2).value.getProperties().getOdeReceivedAt());
+
+ } catch (JsonMappingException e) {
+ e.printStackTrace();
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapWktDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapWktDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..7709120
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/ProcessedMapWktDeduplicatorTopologyTest.java
@@ -0,0 +1,129 @@
+package deduplicator;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedMapWktDeduplicatorTopology;
+import us.dot.its.jpo.geojsonconverter.pojos.geojson.map.ProcessedMap;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import java.util.List;
+
+public class ProcessedMapWktDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.ProcessedMapWKT";
+ String outputTopic = "topic.DeduplicatedProcessedMapWKT";
+
+
+
+ TypeReference> typeReference = new TypeReference<>(){};
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // Reference MAP
+ String inputProcessedMapWkt1 = "";
+
+ // Duplicate of Number 1
+ String inputProcessedMapWkt2 = "";
+
+ // A different Message entirely
+ String inputProcessedMapWkt3 = "";
+
+ // Message 1 but 1 hour later
+ String inputProcessedMapWkt4 = "";
+
+ String key = "{\"rsuId\":\"10.11.81.12\",\"intersectionId\":12109,\"region\":-1}";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+
+ @Before
+ public void setup() throws IOException {
+ // Load test files from resources
+
+ // Reference MAP
+ inputProcessedMapWkt1 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference.json")));
+
+ // Duplicate of Number 1
+ inputProcessedMapWkt2 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference.json")));
+
+ // A different Message entirely
+ inputProcessedMapWkt3 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-different.json")));
+
+ // Message 1 but 1 hour later
+ inputProcessedMapWkt4 = new String(Files.readAllBytes(Paths.get("src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference-1-hour-later.json")));
+ }
+
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicProcessedMapWKT(inputTopic);
+ props.setKafkaTopicDeduplicatedProcessedMapWKT(outputTopic);
+
+ ProcessedMapWktDeduplicatorTopology processedMapDeduplicatorTopology = new ProcessedMapWktDeduplicatorTopology(props, null);
+
+ Topology topology = processedMapDeduplicatorTopology.buildTopology();
+ objectMapper.registerModule(new JavaTimeModule());
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputProcessedMapData = driver.createInputTopic(
+ inputTopic,
+ Serdes.String().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic> outputProcessedMapData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ JsonSerdes.ProcessedMapWKT().deserializer());
+
+ inputProcessedMapData.pipeInput(key, inputProcessedMapWkt1);
+ inputProcessedMapData.pipeInput(key, inputProcessedMapWkt2);
+ inputProcessedMapData.pipeInput(key, inputProcessedMapWkt3);
+ inputProcessedMapData.pipeInput(key, inputProcessedMapWkt4);
+
+ List>> mapDeduplicatorResults = outputProcessedMapData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(3, mapDeduplicatorResults.size());
+
+ ProcessedMap map1 = objectMapper.readValue(inputProcessedMapWkt1, typeReference);
+ ProcessedMap map2 = objectMapper.readValue(inputProcessedMapWkt2, typeReference);
+ ProcessedMap map4 = objectMapper.readValue(inputProcessedMapWkt4, typeReference);
+
+ assertEquals(map1.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(0).value.getProperties().getOdeReceivedAt());
+ assertEquals(map2.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(1).value.getProperties().getOdeReceivedAt());
+ assertEquals(map4.getProperties().getOdeReceivedAt(), mapDeduplicatorResults.get(2).value.getProperties().getOdeReceivedAt());
+
+
+
+ } catch (JsonMappingException e) {
+ e.printStackTrace();
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/test/java/deduplicator/ProcessedSpatDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/ProcessedSpatDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..047c629
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/ProcessedSpatDeduplicatorTopologyTest.java
@@ -0,0 +1,117 @@
+package deduplicator;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.ProcessedSpatDeduplicatorTopology;
+import us.dot.its.jpo.geojsonconverter.pojos.spat.ProcessedSpat;
+import us.dot.its.jpo.geojsonconverter.serialization.JsonSerdes;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+
+public class ProcessedSpatDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.ProcessedSpat";
+ String outputTopic = "topic.DeduplicatedProcessedSpat";
+
+
+ TypeReference typeReference = new TypeReference<>(){};
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ // Reference Message
+ String inputProcessedSpat1 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:04:56.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:04:35.176Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":5,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ // Deduplicated Message - Same as Reference.
+ String inputProcessedSpat2 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:05:56.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:04:35.276Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":5,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ // Fast forward 1 minute
+ String inputProcessedSpat3 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:05:57.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:05:36.376Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":5,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ // Remove a Signal Group
+ String inputProcessedSpat4 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:05:56.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:05:36.496Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ // Change the ID of a Signal Group
+ String inputProcessedSpat5 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:05:56.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:05:35.576Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":7,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ // Change the Light State of one of the Signal Groups
+ String inputProcessedSpat6 = "{\"schemaVersion\":1,\"messageType\":\"SPAT\",\"odeReceivedAt\":\"2025-02-01T00:05:56.686Z\",\"originIp\":\"172.20.0.1\",\"intersectionId\":12111,\"cti4501Conformant\":false,\"validationMessages\":[{\"message\":\"$.payload.data.timeStamp: is missing but it is required\",\"jsonPath\":\"$.payload.data\",\"schemaPath\":\"#/$defs/J2735SPAT/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id.region: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].id\",\"schemaPath\":\"#/$defs/J2735IntersectionReferenceID/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[0].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[1].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[2].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[3].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[4].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.startTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"},{\"message\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing.nextTime: is missing but it is required\",\"jsonPath\":\"$.payload.data.intersectionStateList.intersectionStatelist[0].states.movementList[5].state_time_speed.movementEventList[0].timing\",\"schemaPath\":\"#/$defs/J2735TimeChangeDetails/required\"}],\"revision\":0,\"status\":{\"manualControlIsEnabled\":false,\"stopTimeIsActivated\":false,\"failureFlash\":false,\"preemptIsActive\":false,\"signalPriorityIsActive\":false,\"fixedTimeOperation\":false,\"trafficDependentOperation\":false,\"standbyOperation\":false,\"failureMode\":false,\"off\":false,\"recentMAPmessageUpdate\":false,\"recentChangeInMAPassignedLanesIDsUsed\":false,\"noValidMAPisAvailableAtThisTime\":false,\"noValidSPATisAvailableAtThisTime\":false},\"utcTimeStamp\":\"2025-02-01T00:05:35.676Z\",\"states\":[{\"signalGroup\":2,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":4,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:58.1Z\",\"maxEndTime\":\"2025-02-01T00:36:58.1Z\"}}]},{\"signalGroup\":6,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:52Z\",\"maxEndTime\":\"2025-02-01T00:36:52.1Z\"}}]},{\"signalGroup\":8,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":1,\"stateTimeSpeed\":[{\"eventState\":\"PROTECTED_MOVEMENT_ALLOWED\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]},{\"signalGroup\":5,\"stateTimeSpeed\":[{\"eventState\":\"STOP_AND_REMAIN\",\"timing\":{\"minEndTime\":\"2025-02-01T00:36:25.2Z\",\"maxEndTime\":\"2025-02-01T00:36:25.2Z\"}}]}]}";
+
+ String key = "{\"rsuId\": \"10.164.6.16\", \"intersectionId\": 6311, \"region\": -1}";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicProcessedSpat(inputTopic);
+ props.setKafkaTopicDeduplicatedProcessedSpat(outputTopic);
+
+ ProcessedSpatDeduplicatorTopology processedSpatDeduplicatorTopology = new ProcessedSpatDeduplicatorTopology(props, null);
+
+ Topology topology = processedSpatDeduplicatorTopology.buildTopology();
+ objectMapper.registerModule(new JavaTimeModule());
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputProcessedSpatData = driver.createInputTopic(
+ inputTopic,
+ Serdes.String().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic outputProcessedSpatData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ JsonSerdes.ProcessedSpat().deserializer());
+
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat1);
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat2);
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat3);
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat4);
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat5);
+ inputProcessedSpatData.pipeInput(key, inputProcessedSpat6);
+
+ List> spatDeduplicatorResults = outputProcessedSpatData.readKeyValuesToList();
+
+ // validate that only 5 messages make it through
+ assertEquals(5, spatDeduplicatorResults.size());
+
+ ProcessedSpat spat1 = objectMapper.readValue(inputProcessedSpat1, typeReference);
+ ProcessedSpat spat3 = objectMapper.readValue(inputProcessedSpat3, typeReference); // forwarded because the time on the message changes by 1 minute
+ ProcessedSpat spat4 = objectMapper.readValue(inputProcessedSpat4, typeReference); // forwarded because the signal state changes
+ ProcessedSpat spat5 = objectMapper.readValue(inputProcessedSpat5, typeReference); // forwarded because the number of signal groups changed
+ ProcessedSpat spat6 = objectMapper.readValue(inputProcessedSpat6, typeReference); // forwarded because a signal group ID changed
+
+ assertEquals(spat1.getUtcTimeStamp(), spatDeduplicatorResults.get(0).value.getUtcTimeStamp());
+ assertEquals(spat3.getUtcTimeStamp(), spatDeduplicatorResults.get(1).value.getUtcTimeStamp());
+ assertEquals(spat4.getUtcTimeStamp(), spatDeduplicatorResults.get(2).value.getUtcTimeStamp());
+ assertEquals(spat5.getUtcTimeStamp(), spatDeduplicatorResults.get(3).value.getUtcTimeStamp());
+ assertEquals(spat6.getUtcTimeStamp(), spatDeduplicatorResults.get(4).value.getUtcTimeStamp());
+
+
+ } catch (JsonMappingException e) {
+ e.printStackTrace();
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/test/java/deduplicator/TimDeduplicatorTopologyTest.java b/jpo-deduplicator/src/test/java/deduplicator/TimDeduplicatorTopologyTest.java
new file mode 100644
index 0000000..fd6d3e9
--- /dev/null
+++ b/jpo-deduplicator/src/test/java/deduplicator/TimDeduplicatorTopologyTest.java
@@ -0,0 +1,89 @@
+package deduplicator;
+
+import org.apache.kafka.common.serialization.Serdes;
+import org.apache.kafka.streams.KeyValue;
+import org.apache.kafka.streams.TestInputTopic;
+import org.apache.kafka.streams.TestOutputTopic;
+import org.apache.kafka.streams.Topology;
+import org.apache.kafka.streams.TopologyTestDriver;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import us.dot.its.jpo.deduplicator.DeduplicatorProperties;
+import us.dot.its.jpo.deduplicator.deduplicator.topologies.TimDeduplicatorTopology;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import java.util.List;
+
+
+public class TimDeduplicatorTopologyTest {
+
+ String inputTopic = "topic.OdeTimJson";
+ String outputTopic = "topic.DeduplicatedOdeTimJson";
+
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ //Original Message
+ String inputTim1 = "{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"b2d15f2d-7461-4083-b3df-b4efadab4d17\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-02-01T00:19:45.739Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"msgCnt\":93,\"timeStamp\":291367,\"packetID\":\"4F4354455420535452\",\"urlB\":\"IA5\",\"dataFrames\":[{\"doNotUse1\":0,\"frameType\":\"commercialSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":1150,\"startTime\":473045,\"durationTime\":3687,\"priority\":7,\"doNotUse2\":22,\"regions\":[{\"name\":\"IA\",\"id\":{\"region\":64764,\"id\":18642},\"anchor\":{\"lat\":172032029,\"long\":-1025506517,\"elevation\":13386},\"laneWidth\":19949,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":9,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":252,\"offsetXaxis\":{\"large\":-5120},\"offsetYaxis\":{\"small\":-585},\"rotateXY\":8692,\"scaleXaxis\":-422,\"scaleYaxis\":464}}}}}},{\"name\":\"IA\",\"id\":{\"region\":2911,\"id\":24513},\"anchor\":{\"lat\":217001329,\"long\":-436271951,\"elevation\":28809},\"laneWidth\":30930,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":8,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL4\":{\"lon\":115258,\"lat\":80231}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"hydrantPresent\",\"mergePoint\",\"divergePoint\",\"reserved\"],\"disabled\":[\"transitStopOnRight\",\"adaptiveTimingPresent\",\"loadingzoneOnLeft\",\"costToPark\"],\"enabled\":[\"curbOnLeft\"],\"data\":[{\"speedLimits\":[{\"type\":\"truckNightMaxSpeed\",\"speed\":6769},{\"type\":\"truckMaxSpeed\",\"speed\":4438},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":2679},{\"type\":\"vehiclesWithTrailersNightMaxSpeed\",\"speed\":3110},{\"type\":\"vehicleMaxSpeed\",\"speed\":1987}]}],\"dWidth\":-188,\"dElevation\":-61}},{\"delta\":{\"node-LL6\":{\"lon\":5893850,\"lat\":-6770613}},\"attributes\":{\"localNode\":[\"closedToTraffic\"],\"disabled\":[\"bikeBoxInFront\"],\"enabled\":[\"mergingLaneRight\"],\"data\":[{\"laneCrownPointLeft\":-17}],\"dWidth\":-396,\"dElevation\":-88}},{\"delta\":{\"node-LL1\":{\"lon\":-924,\"lat\":-109}},\"attributes\":{\"localNode\":[\"downstreamStopLine\",\"roundedCapStyleB\"],\"disabled\":[\"whiteLine\",\"partialCurbIntrusion\"],\"enabled\":[\"loadingzoneOnLeft\",\"audibleSignalingPresent\",\"freeParking\"],\"data\":[{\"laneCrownPointCenter\":55},{\"laneAngle\":-98}],\"dWidth\":-319,\"dElevation\":-89}}]}}}}},{\"name\":\"IA\",\"id\":{\"region\":23018,\"id\":35659},\"anchor\":{\"lat\":-544509288,\"long\":-1334375239,\"elevation\":-3608},\"laneWidth\":14780,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":true,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":5,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":108,\"offsetXaxis\":{\"small\":-1574},\"offsetYaxis\":{\"large\":-635},\"rotateXY\":21792,\"scaleXaxis\":689,\"scaleYaxis\":640}}}}}},{\"name\":\"I\",\"id\":{\"region\":32256,\"id\":28265},\"anchor\":{\"lat\":725366646,\"long\":-566506763,\"elevation\":6227},\"laneWidth\":26178,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":1,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL5\":{\"lon\":2030663,\"lat\":-517129}},\"attributes\":{\"localNode\":[\"safeIsland\",\"hydrantPresent\",\"curbPresentAtStepOff\"],\"disabled\":[\"sharedWithTrackedVehicle\",\"transitStopOnLeft\",\"headInParking\",\"audibleSignalingPresent\"],\"enabled\":[\"doNotBlock\",\"mergingLaneLeft\"],\"data\":[{\"laneCrownPointRight\":48},{\"laneCrownPointRight\":-114}],\"dWidth\":-505,\"dElevation\":-119}},{\"delta\":{\"node-LL6\":{\"lon\":-5645920,\"lat\":-5242762}},\"attributes\":{\"localNode\":[\"reserved\",\"safeIsland\",\"mergePoint\"],\"disabled\":[\"turnOutPointOnLeft\"],\"enabled\":[\"timeRestrictionsOnParking\",\"adaptiveTimingPresent\",\"turnOutPointOnRight\",\"bikeBoxInFront\"],\"data\":[{\"laneCrownPointCenter\":-58},{\"pathEndPointAngle\":-55},{\"pathEndPointAngle\":-58}],\"dWidth\":472,\"dElevation\":-190}}]}}}}}],\"doNotUse3\":16,\"doNotUse4\":13,\"content\":{\"genericSign\":[{\"item\":{\"itis\":61599}},{\"item\":{\"itis\":47850}},{\"item\":{\"itis\":39204}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5S\"}}]},\"url\":\"IA5\"},{\"doNotUse1\":7,\"frameType\":\"roadSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":2457,\"startTime\":66787,\"durationTime\":19034,\"priority\":4,\"doNotUse2\":16,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":61846,\"id\":12218},\"anchor\":{\"lat\":202451669,\"long\":-1016248785,\"elevation\":14777},\"laneWidth\":4825,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":true,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100meters\",\"laneWidth\":23305,\"circle\":{\"center\":{\"lat\":257084126,\"long\":-1572221105,\"elevation\":10372},\"radius\":3021,\"units\":\"cm2-5\"}}}},{\"name\":\"IA5S\",\"id\":{\"region\":44916,\"id\":14928},\"anchor\":{\"lat\":-391962488,\"long\":-1442690475,\"elevation\":975},\"laneWidth\":8081,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":15,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":216,\"offsetXaxis\":{\"small\":682},\"offsetYaxis\":{\"large\":-6571},\"rotateXY\":11786,\"scaleXaxis\":-269,\"scaleYaxis\":-432}}}}}},{\"name\":\"IA5\",\"id\":{\"region\":15268,\"id\":63916},\"anchor\":{\"lat\":-14883901,\"long\":1470459302,\"elevation\":47965},\"laneWidth\":374,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100000meters\",\"area\":{\"circle\":{\"center\":{\"lat\":223434207,\"long\":-714422034,\"elevation\":41663},\"radius\":737,\"units\":\"cm2-5\"}}}}}],\"doNotUse3\":2,\"doNotUse4\":31,\"content\":{\"workZone\":[{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"itis\":52884}}]},\"url\":\"I\"},{\"doNotUse1\":16,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":604037802,\"long\":-124613998,\"elevation\":46289},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":true,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"guide\",\"crc\":\"4F43\"}},\"startYear\":135,\"startTime\":30119,\"durationTime\":17072,\"priority\":7,\"doNotUse2\":6,\"regions\":[{\"name\":\"IA5S\",\"id\":{\"region\":35731,\"id\":64365},\"anchor\":{\"lat\":251341270,\"long\":-1550588968,\"elevation\":18073},\"laneWidth\":19174,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":true},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":19339,\"circle\":{\"center\":{\"lat\":-590142898,\"long\":192563845,\"elevation\":3040},\"radius\":734,\"units\":\"meter\"}}}},{\"name\":\"IA5\",\"id\":{\"region\":13160,\"id\":48242},\"anchor\":{\"lat\":227302831,\"long\":-891580621,\"elevation\":7072},\"laneWidth\":5923,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"area\":{\"circle\":{\"center\":{\"lat\":368610426,\"long\":-1703460317,\"elevation\":1004},\"radius\":2194,\"units\":\"meter\"}}}}},{\"name\":\"I\",\"id\":{\"region\":58508,\"id\":15927},\"anchor\":{\"lat\":892488592,\"long\":-431640924,\"elevation\":41561},\"laneWidth\":26527,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"regionPointSet\":{\"anchor\":{\"lat\":-113602543,\"long\":717746718,\"elevation\":49498},\"scale\":1,\"nodeList\":[{\"xOffset\":27670,\"yOffset\":-14790,\"zOffset\":-21638},{\"xOffset\":3020,\"yOffset\":-9872,\"zOffset\":-109},{\"xOffset\":-24382,\"yOffset\":23709,\"zOffset\":-862},{\"xOffset\":-26476,\"yOffset\":-6439,\"zOffset\":-23411}]}}}}},{\"name\":\"IA5\",\"id\":{\"region\":379,\"id\":22438},\"anchor\":{\"lat\":-281093797,\"long\":556669965,\"elevation\":29497},\"laneWidth\":7880,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor500000meters\",\"laneWidth\":2148,\"circle\":{\"center\":{\"lat\":163173661,\"long\":-872411303,\"elevation\":55588},\"radius\":489,\"units\":\"cm2-5\"}}}}],\"doNotUse3\":8,\"doNotUse4\":29,\"content\":{\"advisory\":[{\"item\":{\"itis\":44093}},{\"item\":{\"itis\":65240}},{\"item\":{\"text\":\"IA\"}}]},\"url\":\"I\"},{\"doNotUse1\":31,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":-864002503,\"long\":-654286715,\"elevation\":43804},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":3076,\"startTime\":282183,\"durationTime\":14436,\"priority\":6,\"doNotUse2\":11,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":11880,\"id\":33814},\"anchor\":{\"lat\":51295938,\"long\":799818234,\"elevation\":10466},\"laneWidth\":10554,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":10,\"offset\":{\"xy\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"mergePoint\"],\"disabled\":[\"transitStopOnLeft\",\"bikeBoxInFront\",\"doNotBlock\"],\"enabled\":[\"mergingLaneLeft\",\"mergingLaneRight\"],\"data\":[{\"laneCrownPointCenter\":91},{\"laneCrownPointLeft\":-60},{\"laneCrownPointLeft\":-118}],\"dWidth\":-80,\"dElevation\":-211}},{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"hydrantPresent\",\"roundedCapStyleA\",\"roundedCapStyleB\"],\"disabled\":[\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnRight\",\"curbOnLeft\"],\"data\":[{\"laneCrownPointCenter\":-3},{\"laneCrownPointCenter\":-23},{\"speedLimits\":[{\"type\":\"vehicleMinSpeed\",\"speed\":5260},{\"type\":\"maxSpeedInConstructionZone\",\"speed\":7676}]}],\"dWidth\":-98,\"dElevation\":-300}},{\"delta\":{\"node-XY5\":{\"x\":6552,\"y\":-7382}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"stopLine\",\"reserved\",\"roundedCapStyleB\"],\"disabled\":[\"curbOnLeft\",\"turnOutPointOnRight\",\"whiteLine\",\"curbOnRight\"],\"enabled\":[\"sharedWithTrackedVehicle\",\"audibleSignalingPresent\",\"headInParking\"],\"data\":[{\"laneCrownPointCenter\":-7},{\"laneAngle\":68},{\"laneCrownPointLeft\":-39}],\"dWidth\":287,\"dElevation\":510}},{\"delta\":{\"node-XY1\":{\"x\":-310,\"y\":-500}},\"attributes\":{\"localNode\":[\"roundedCapStyleA\"],\"disabled\":[\"timeRestrictionsOnParking\",\"reserved\",\"parallelParking\",\"midBlockCurbPresent\"],\"enabled\":[\"transitStopOnRight\",\"whiteLine\",\"taperToCenterLine\",\"adjacentParkingOnLeft\",\"timeRestrictionsOnParking\"],\"data\":[{\"laneAngle\":-59},{\"laneCrownPointCenter\":105},{\"laneCrownPointCenter\":25},{\"speedLimits\":[{\"type\":\"vehicleNightMaxSpeed\",\"speed\":2245},{\"type\":\"vehicleMaxSpeed\",\"speed\":1700}]},{\"speedLimits\":[{\"type\":\"maxSpeedInSchoolZone\",\"speed\":7839},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":1190},{\"type\":\"truckMaxSpeed\",\"speed\":3947}]}],\"dWidth\":497,\"dElevation\":-208}},{\"delta\":{\"node-LatLon\":{\"lon\":-1625296958,\"lat\":501091223}},\"attributes\":{\"localNode\":[\"downstreamStartNode\",\"downstreamStopLine\",\"safeIsland\"],\"disabled\":[\"adjacentParkingOnLeft\",\"partialCurbIntrusion\",\"taperToRight\"],\"enabled\":[\"unEvenPavementPresent\",\"adjacentParkingOnRight\"],\"data\":[{\"laneCrownPointCenter\":86}],\"dWidth\":-90,\"dElevation\":131}}]}}}}},{\"name\":\"IA5S\",\"id\":{\"region\":48039,\"id\":14622},\"anchor\":{\"lat\":419808681,\"long\":-1470200813,\"elevation\":37213},\"laneWidth\":25845,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":true,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":25719,\"circle\":{\"center\":{\"lat\":-666313075,\"long\":639822734,\"elevation\":29597},\"radius\":1325,\"units\":\"foot\"}}}}],\"doNotUse3\":11,\"doNotUse4\":27,\"content\":{\"speedLimit\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"IA\"},{\"doNotUse1\":18,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":889823043,\"long\":-537303585,\"elevation\":29359},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":1652,\"startTime\":115878,\"durationTime\":7970,\"priority\":6,\"doNotUse2\":27,\"regions\":[{\"name\":\"I\",\"id\":{\"region\":26015,\"id\":40525},\"anchor\":{\"lat\":112058765,\"long\":1125609019,\"elevation\":54648},\"laneWidth\":31409,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":733403986,\"long\":1001009347,\"elevation\":23252},\"laneWidth\":14952,\"directionality\":\"unavailable\",\"nodeList\":{\"computed\":{\"referenceLaneId\":188,\"offsetXaxis\":{\"large\":-8154},\"offsetYaxis\":{\"large\":-28485},\"rotateXY\":224,\"scaleXaxis\":32,\"scaleYaxis\":1787}}}}}}}],\"doNotUse3\":14,\"doNotUse4\":21,\"content\":{\"exitService\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"I\"}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation\"}}";
+
+ // Shifted Forward .1 seconds - Should be deduplicated
+ String inputTim2 = "{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"b2d15f2d-7461-4083-b3df-b4efadab4d17\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-02-01T00:19:45.839Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"msgCnt\":93,\"timeStamp\":291367,\"packetID\":\"4F4354455420535452\",\"urlB\":\"IA5\",\"dataFrames\":[{\"doNotUse1\":0,\"frameType\":\"commercialSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":1150,\"startTime\":473045,\"durationTime\":3687,\"priority\":7,\"doNotUse2\":22,\"regions\":[{\"name\":\"IA\",\"id\":{\"region\":64764,\"id\":18642},\"anchor\":{\"lat\":172032029,\"long\":-1025506517,\"elevation\":13386},\"laneWidth\":19949,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":9,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":252,\"offsetXaxis\":{\"large\":-5120},\"offsetYaxis\":{\"small\":-585},\"rotateXY\":8692,\"scaleXaxis\":-422,\"scaleYaxis\":464}}}}}},{\"name\":\"IA\",\"id\":{\"region\":2911,\"id\":24513},\"anchor\":{\"lat\":217001329,\"long\":-436271951,\"elevation\":28809},\"laneWidth\":30930,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":8,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL4\":{\"lon\":115258,\"lat\":80231}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"hydrantPresent\",\"mergePoint\",\"divergePoint\",\"reserved\"],\"disabled\":[\"transitStopOnRight\",\"adaptiveTimingPresent\",\"loadingzoneOnLeft\",\"costToPark\"],\"enabled\":[\"curbOnLeft\"],\"data\":[{\"speedLimits\":[{\"type\":\"truckNightMaxSpeed\",\"speed\":6769},{\"type\":\"truckMaxSpeed\",\"speed\":4438},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":2679},{\"type\":\"vehiclesWithTrailersNightMaxSpeed\",\"speed\":3110},{\"type\":\"vehicleMaxSpeed\",\"speed\":1987}]}],\"dWidth\":-188,\"dElevation\":-61}},{\"delta\":{\"node-LL6\":{\"lon\":5893850,\"lat\":-6770613}},\"attributes\":{\"localNode\":[\"closedToTraffic\"],\"disabled\":[\"bikeBoxInFront\"],\"enabled\":[\"mergingLaneRight\"],\"data\":[{\"laneCrownPointLeft\":-17}],\"dWidth\":-396,\"dElevation\":-88}},{\"delta\":{\"node-LL1\":{\"lon\":-924,\"lat\":-109}},\"attributes\":{\"localNode\":[\"downstreamStopLine\",\"roundedCapStyleB\"],\"disabled\":[\"whiteLine\",\"partialCurbIntrusion\"],\"enabled\":[\"loadingzoneOnLeft\",\"audibleSignalingPresent\",\"freeParking\"],\"data\":[{\"laneCrownPointCenter\":55},{\"laneAngle\":-98}],\"dWidth\":-319,\"dElevation\":-89}}]}}}}},{\"name\":\"IA\",\"id\":{\"region\":23018,\"id\":35659},\"anchor\":{\"lat\":-544509288,\"long\":-1334375239,\"elevation\":-3608},\"laneWidth\":14780,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":true,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":5,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":108,\"offsetXaxis\":{\"small\":-1574},\"offsetYaxis\":{\"large\":-635},\"rotateXY\":21792,\"scaleXaxis\":689,\"scaleYaxis\":640}}}}}},{\"name\":\"I\",\"id\":{\"region\":32256,\"id\":28265},\"anchor\":{\"lat\":725366646,\"long\":-566506763,\"elevation\":6227},\"laneWidth\":26178,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":1,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL5\":{\"lon\":2030663,\"lat\":-517129}},\"attributes\":{\"localNode\":[\"safeIsland\",\"hydrantPresent\",\"curbPresentAtStepOff\"],\"disabled\":[\"sharedWithTrackedVehicle\",\"transitStopOnLeft\",\"headInParking\",\"audibleSignalingPresent\"],\"enabled\":[\"doNotBlock\",\"mergingLaneLeft\"],\"data\":[{\"laneCrownPointRight\":48},{\"laneCrownPointRight\":-114}],\"dWidth\":-505,\"dElevation\":-119}},{\"delta\":{\"node-LL6\":{\"lon\":-5645920,\"lat\":-5242762}},\"attributes\":{\"localNode\":[\"reserved\",\"safeIsland\",\"mergePoint\"],\"disabled\":[\"turnOutPointOnLeft\"],\"enabled\":[\"timeRestrictionsOnParking\",\"adaptiveTimingPresent\",\"turnOutPointOnRight\",\"bikeBoxInFront\"],\"data\":[{\"laneCrownPointCenter\":-58},{\"pathEndPointAngle\":-55},{\"pathEndPointAngle\":-58}],\"dWidth\":472,\"dElevation\":-190}}]}}}}}],\"doNotUse3\":16,\"doNotUse4\":13,\"content\":{\"genericSign\":[{\"item\":{\"itis\":61599}},{\"item\":{\"itis\":47850}},{\"item\":{\"itis\":39204}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5S\"}}]},\"url\":\"IA5\"},{\"doNotUse1\":7,\"frameType\":\"roadSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":2457,\"startTime\":66787,\"durationTime\":19034,\"priority\":4,\"doNotUse2\":16,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":61846,\"id\":12218},\"anchor\":{\"lat\":202451669,\"long\":-1016248785,\"elevation\":14777},\"laneWidth\":4825,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":true,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100meters\",\"laneWidth\":23305,\"circle\":{\"center\":{\"lat\":257084126,\"long\":-1572221105,\"elevation\":10372},\"radius\":3021,\"units\":\"cm2-5\"}}}},{\"name\":\"IA5S\",\"id\":{\"region\":44916,\"id\":14928},\"anchor\":{\"lat\":-391962488,\"long\":-1442690475,\"elevation\":975},\"laneWidth\":8081,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":15,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":216,\"offsetXaxis\":{\"small\":682},\"offsetYaxis\":{\"large\":-6571},\"rotateXY\":11786,\"scaleXaxis\":-269,\"scaleYaxis\":-432}}}}}},{\"name\":\"IA5\",\"id\":{\"region\":15268,\"id\":63916},\"anchor\":{\"lat\":-14883901,\"long\":1470459302,\"elevation\":47965},\"laneWidth\":374,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100000meters\",\"area\":{\"circle\":{\"center\":{\"lat\":223434207,\"long\":-714422034,\"elevation\":41663},\"radius\":737,\"units\":\"cm2-5\"}}}}}],\"doNotUse3\":2,\"doNotUse4\":31,\"content\":{\"workZone\":[{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"itis\":52884}}]},\"url\":\"I\"},{\"doNotUse1\":16,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":604037802,\"long\":-124613998,\"elevation\":46289},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":true,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"guide\",\"crc\":\"4F43\"}},\"startYear\":135,\"startTime\":30119,\"durationTime\":17072,\"priority\":7,\"doNotUse2\":6,\"regions\":[{\"name\":\"IA5S\",\"id\":{\"region\":35731,\"id\":64365},\"anchor\":{\"lat\":251341270,\"long\":-1550588968,\"elevation\":18073},\"laneWidth\":19174,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":true},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":19339,\"circle\":{\"center\":{\"lat\":-590142898,\"long\":192563845,\"elevation\":3040},\"radius\":734,\"units\":\"meter\"}}}},{\"name\":\"IA5\",\"id\":{\"region\":13160,\"id\":48242},\"anchor\":{\"lat\":227302831,\"long\":-891580621,\"elevation\":7072},\"laneWidth\":5923,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"area\":{\"circle\":{\"center\":{\"lat\":368610426,\"long\":-1703460317,\"elevation\":1004},\"radius\":2194,\"units\":\"meter\"}}}}},{\"name\":\"I\",\"id\":{\"region\":58508,\"id\":15927},\"anchor\":{\"lat\":892488592,\"long\":-431640924,\"elevation\":41561},\"laneWidth\":26527,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"regionPointSet\":{\"anchor\":{\"lat\":-113602543,\"long\":717746718,\"elevation\":49498},\"scale\":1,\"nodeList\":[{\"xOffset\":27670,\"yOffset\":-14790,\"zOffset\":-21638},{\"xOffset\":3020,\"yOffset\":-9872,\"zOffset\":-109},{\"xOffset\":-24382,\"yOffset\":23709,\"zOffset\":-862},{\"xOffset\":-26476,\"yOffset\":-6439,\"zOffset\":-23411}]}}}}},{\"name\":\"IA5\",\"id\":{\"region\":379,\"id\":22438},\"anchor\":{\"lat\":-281093797,\"long\":556669965,\"elevation\":29497},\"laneWidth\":7880,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor500000meters\",\"laneWidth\":2148,\"circle\":{\"center\":{\"lat\":163173661,\"long\":-872411303,\"elevation\":55588},\"radius\":489,\"units\":\"cm2-5\"}}}}],\"doNotUse3\":8,\"doNotUse4\":29,\"content\":{\"advisory\":[{\"item\":{\"itis\":44093}},{\"item\":{\"itis\":65240}},{\"item\":{\"text\":\"IA\"}}]},\"url\":\"I\"},{\"doNotUse1\":31,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":-864002503,\"long\":-654286715,\"elevation\":43804},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":3076,\"startTime\":282183,\"durationTime\":14436,\"priority\":6,\"doNotUse2\":11,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":11880,\"id\":33814},\"anchor\":{\"lat\":51295938,\"long\":799818234,\"elevation\":10466},\"laneWidth\":10554,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":10,\"offset\":{\"xy\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"mergePoint\"],\"disabled\":[\"transitStopOnLeft\",\"bikeBoxInFront\",\"doNotBlock\"],\"enabled\":[\"mergingLaneLeft\",\"mergingLaneRight\"],\"data\":[{\"laneCrownPointCenter\":91},{\"laneCrownPointLeft\":-60},{\"laneCrownPointLeft\":-118}],\"dWidth\":-80,\"dElevation\":-211}},{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"hydrantPresent\",\"roundedCapStyleA\",\"roundedCapStyleB\"],\"disabled\":[\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnRight\",\"curbOnLeft\"],\"data\":[{\"laneCrownPointCenter\":-3},{\"laneCrownPointCenter\":-23},{\"speedLimits\":[{\"type\":\"vehicleMinSpeed\",\"speed\":5260},{\"type\":\"maxSpeedInConstructionZone\",\"speed\":7676}]}],\"dWidth\":-98,\"dElevation\":-300}},{\"delta\":{\"node-XY5\":{\"x\":6552,\"y\":-7382}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"stopLine\",\"reserved\",\"roundedCapStyleB\"],\"disabled\":[\"curbOnLeft\",\"turnOutPointOnRight\",\"whiteLine\",\"curbOnRight\"],\"enabled\":[\"sharedWithTrackedVehicle\",\"audibleSignalingPresent\",\"headInParking\"],\"data\":[{\"laneCrownPointCenter\":-7},{\"laneAngle\":68},{\"laneCrownPointLeft\":-39}],\"dWidth\":287,\"dElevation\":510}},{\"delta\":{\"node-XY1\":{\"x\":-310,\"y\":-500}},\"attributes\":{\"localNode\":[\"roundedCapStyleA\"],\"disabled\":[\"timeRestrictionsOnParking\",\"reserved\",\"parallelParking\",\"midBlockCurbPresent\"],\"enabled\":[\"transitStopOnRight\",\"whiteLine\",\"taperToCenterLine\",\"adjacentParkingOnLeft\",\"timeRestrictionsOnParking\"],\"data\":[{\"laneAngle\":-59},{\"laneCrownPointCenter\":105},{\"laneCrownPointCenter\":25},{\"speedLimits\":[{\"type\":\"vehicleNightMaxSpeed\",\"speed\":2245},{\"type\":\"vehicleMaxSpeed\",\"speed\":1700}]},{\"speedLimits\":[{\"type\":\"maxSpeedInSchoolZone\",\"speed\":7839},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":1190},{\"type\":\"truckMaxSpeed\",\"speed\":3947}]}],\"dWidth\":497,\"dElevation\":-208}},{\"delta\":{\"node-LatLon\":{\"lon\":-1625296958,\"lat\":501091223}},\"attributes\":{\"localNode\":[\"downstreamStartNode\",\"downstreamStopLine\",\"safeIsland\"],\"disabled\":[\"adjacentParkingOnLeft\",\"partialCurbIntrusion\",\"taperToRight\"],\"enabled\":[\"unEvenPavementPresent\",\"adjacentParkingOnRight\"],\"data\":[{\"laneCrownPointCenter\":86}],\"dWidth\":-90,\"dElevation\":131}}]}}}}},{\"name\":\"IA5S\",\"id\":{\"region\":48039,\"id\":14622},\"anchor\":{\"lat\":419808681,\"long\":-1470200813,\"elevation\":37213},\"laneWidth\":25845,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":true,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":25719,\"circle\":{\"center\":{\"lat\":-666313075,\"long\":639822734,\"elevation\":29597},\"radius\":1325,\"units\":\"foot\"}}}}],\"doNotUse3\":11,\"doNotUse4\":27,\"content\":{\"speedLimit\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"IA\"},{\"doNotUse1\":18,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":889823043,\"long\":-537303585,\"elevation\":29359},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":1652,\"startTime\":115878,\"durationTime\":7970,\"priority\":6,\"doNotUse2\":27,\"regions\":[{\"name\":\"I\",\"id\":{\"region\":26015,\"id\":40525},\"anchor\":{\"lat\":112058765,\"long\":1125609019,\"elevation\":54648},\"laneWidth\":31409,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":733403986,\"long\":1001009347,\"elevation\":23252},\"laneWidth\":14952,\"directionality\":\"unavailable\",\"nodeList\":{\"computed\":{\"referenceLaneId\":188,\"offsetXaxis\":{\"large\":-8154},\"offsetYaxis\":{\"large\":-28485},\"rotateXY\":224,\"scaleXaxis\":32,\"scaleYaxis\":1787}}}}}}}],\"doNotUse3\":14,\"doNotUse4\":21,\"content\":{\"exitService\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"I\"}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation\"}}";
+
+ // Shifted Forward 1 hour Should be allowed to pass through
+ String inputTim3 = "{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"b2d15f2d-7461-4083-b3df-b4efadab4d17\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-02-01T01:19:46.739Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"msgCnt\":93,\"timeStamp\":291367,\"packetID\":\"4F4354455420535452\",\"urlB\":\"IA5\",\"dataFrames\":[{\"doNotUse1\":0,\"frameType\":\"commercialSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":1150,\"startTime\":473045,\"durationTime\":3687,\"priority\":7,\"doNotUse2\":22,\"regions\":[{\"name\":\"IA\",\"id\":{\"region\":64764,\"id\":18642},\"anchor\":{\"lat\":172032029,\"long\":-1025506517,\"elevation\":13386},\"laneWidth\":19949,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":9,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":252,\"offsetXaxis\":{\"large\":-5120},\"offsetYaxis\":{\"small\":-585},\"rotateXY\":8692,\"scaleXaxis\":-422,\"scaleYaxis\":464}}}}}},{\"name\":\"IA\",\"id\":{\"region\":2911,\"id\":24513},\"anchor\":{\"lat\":217001329,\"long\":-436271951,\"elevation\":28809},\"laneWidth\":30930,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":8,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL4\":{\"lon\":115258,\"lat\":80231}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"hydrantPresent\",\"mergePoint\",\"divergePoint\",\"reserved\"],\"disabled\":[\"transitStopOnRight\",\"adaptiveTimingPresent\",\"loadingzoneOnLeft\",\"costToPark\"],\"enabled\":[\"curbOnLeft\"],\"data\":[{\"speedLimits\":[{\"type\":\"truckNightMaxSpeed\",\"speed\":6769},{\"type\":\"truckMaxSpeed\",\"speed\":4438},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":2679},{\"type\":\"vehiclesWithTrailersNightMaxSpeed\",\"speed\":3110},{\"type\":\"vehicleMaxSpeed\",\"speed\":1987}]}],\"dWidth\":-188,\"dElevation\":-61}},{\"delta\":{\"node-LL6\":{\"lon\":5893850,\"lat\":-6770613}},\"attributes\":{\"localNode\":[\"closedToTraffic\"],\"disabled\":[\"bikeBoxInFront\"],\"enabled\":[\"mergingLaneRight\"],\"data\":[{\"laneCrownPointLeft\":-17}],\"dWidth\":-396,\"dElevation\":-88}},{\"delta\":{\"node-LL1\":{\"lon\":-924,\"lat\":-109}},\"attributes\":{\"localNode\":[\"downstreamStopLine\",\"roundedCapStyleB\"],\"disabled\":[\"whiteLine\",\"partialCurbIntrusion\"],\"enabled\":[\"loadingzoneOnLeft\",\"audibleSignalingPresent\",\"freeParking\"],\"data\":[{\"laneCrownPointCenter\":55},{\"laneAngle\":-98}],\"dWidth\":-319,\"dElevation\":-89}}]}}}}},{\"name\":\"IA\",\"id\":{\"region\":23018,\"id\":35659},\"anchor\":{\"lat\":-544509288,\"long\":-1334375239,\"elevation\":-3608},\"laneWidth\":14780,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":true,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":5,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":108,\"offsetXaxis\":{\"small\":-1574},\"offsetYaxis\":{\"large\":-635},\"rotateXY\":21792,\"scaleXaxis\":689,\"scaleYaxis\":640}}}}}},{\"name\":\"I\",\"id\":{\"region\":32256,\"id\":28265},\"anchor\":{\"lat\":725366646,\"long\":-566506763,\"elevation\":6227},\"laneWidth\":26178,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":1,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL5\":{\"lon\":2030663,\"lat\":-517129}},\"attributes\":{\"localNode\":[\"safeIsland\",\"hydrantPresent\",\"curbPresentAtStepOff\"],\"disabled\":[\"sharedWithTrackedVehicle\",\"transitStopOnLeft\",\"headInParking\",\"audibleSignalingPresent\"],\"enabled\":[\"doNotBlock\",\"mergingLaneLeft\"],\"data\":[{\"laneCrownPointRight\":48},{\"laneCrownPointRight\":-114}],\"dWidth\":-505,\"dElevation\":-119}},{\"delta\":{\"node-LL6\":{\"lon\":-5645920,\"lat\":-5242762}},\"attributes\":{\"localNode\":[\"reserved\",\"safeIsland\",\"mergePoint\"],\"disabled\":[\"turnOutPointOnLeft\"],\"enabled\":[\"timeRestrictionsOnParking\",\"adaptiveTimingPresent\",\"turnOutPointOnRight\",\"bikeBoxInFront\"],\"data\":[{\"laneCrownPointCenter\":-58},{\"pathEndPointAngle\":-55},{\"pathEndPointAngle\":-58}],\"dWidth\":472,\"dElevation\":-190}}]}}}}}],\"doNotUse3\":16,\"doNotUse4\":13,\"content\":{\"genericSign\":[{\"item\":{\"itis\":61599}},{\"item\":{\"itis\":47850}},{\"item\":{\"itis\":39204}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5S\"}}]},\"url\":\"IA5\"},{\"doNotUse1\":7,\"frameType\":\"roadSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":2457,\"startTime\":66787,\"durationTime\":19034,\"priority\":4,\"doNotUse2\":16,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":61846,\"id\":12218},\"anchor\":{\"lat\":202451669,\"long\":-1016248785,\"elevation\":14777},\"laneWidth\":4825,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":true,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100meters\",\"laneWidth\":23305,\"circle\":{\"center\":{\"lat\":257084126,\"long\":-1572221105,\"elevation\":10372},\"radius\":3021,\"units\":\"cm2-5\"}}}},{\"name\":\"IA5S\",\"id\":{\"region\":44916,\"id\":14928},\"anchor\":{\"lat\":-391962488,\"long\":-1442690475,\"elevation\":975},\"laneWidth\":8081,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":15,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":216,\"offsetXaxis\":{\"small\":682},\"offsetYaxis\":{\"large\":-6571},\"rotateXY\":11786,\"scaleXaxis\":-269,\"scaleYaxis\":-432}}}}}},{\"name\":\"IA5\",\"id\":{\"region\":15268,\"id\":63916},\"anchor\":{\"lat\":-14883901,\"long\":1470459302,\"elevation\":47965},\"laneWidth\":374,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100000meters\",\"area\":{\"circle\":{\"center\":{\"lat\":223434207,\"long\":-714422034,\"elevation\":41663},\"radius\":737,\"units\":\"cm2-5\"}}}}}],\"doNotUse3\":2,\"doNotUse4\":31,\"content\":{\"workZone\":[{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"itis\":52884}}]},\"url\":\"I\"},{\"doNotUse1\":16,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":604037802,\"long\":-124613998,\"elevation\":46289},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":true,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"guide\",\"crc\":\"4F43\"}},\"startYear\":135,\"startTime\":30119,\"durationTime\":17072,\"priority\":7,\"doNotUse2\":6,\"regions\":[{\"name\":\"IA5S\",\"id\":{\"region\":35731,\"id\":64365},\"anchor\":{\"lat\":251341270,\"long\":-1550588968,\"elevation\":18073},\"laneWidth\":19174,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":true},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":19339,\"circle\":{\"center\":{\"lat\":-590142898,\"long\":192563845,\"elevation\":3040},\"radius\":734,\"units\":\"meter\"}}}},{\"name\":\"IA5\",\"id\":{\"region\":13160,\"id\":48242},\"anchor\":{\"lat\":227302831,\"long\":-891580621,\"elevation\":7072},\"laneWidth\":5923,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"area\":{\"circle\":{\"center\":{\"lat\":368610426,\"long\":-1703460317,\"elevation\":1004},\"radius\":2194,\"units\":\"meter\"}}}}},{\"name\":\"I\",\"id\":{\"region\":58508,\"id\":15927},\"anchor\":{\"lat\":892488592,\"long\":-431640924,\"elevation\":41561},\"laneWidth\":26527,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"regionPointSet\":{\"anchor\":{\"lat\":-113602543,\"long\":717746718,\"elevation\":49498},\"scale\":1,\"nodeList\":[{\"xOffset\":27670,\"yOffset\":-14790,\"zOffset\":-21638},{\"xOffset\":3020,\"yOffset\":-9872,\"zOffset\":-109},{\"xOffset\":-24382,\"yOffset\":23709,\"zOffset\":-862},{\"xOffset\":-26476,\"yOffset\":-6439,\"zOffset\":-23411}]}}}}},{\"name\":\"IA5\",\"id\":{\"region\":379,\"id\":22438},\"anchor\":{\"lat\":-281093797,\"long\":556669965,\"elevation\":29497},\"laneWidth\":7880,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor500000meters\",\"laneWidth\":2148,\"circle\":{\"center\":{\"lat\":163173661,\"long\":-872411303,\"elevation\":55588},\"radius\":489,\"units\":\"cm2-5\"}}}}],\"doNotUse3\":8,\"doNotUse4\":29,\"content\":{\"advisory\":[{\"item\":{\"itis\":44093}},{\"item\":{\"itis\":65240}},{\"item\":{\"text\":\"IA\"}}]},\"url\":\"I\"},{\"doNotUse1\":31,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":-864002503,\"long\":-654286715,\"elevation\":43804},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":3076,\"startTime\":282183,\"durationTime\":14436,\"priority\":6,\"doNotUse2\":11,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":11880,\"id\":33814},\"anchor\":{\"lat\":51295938,\"long\":799818234,\"elevation\":10466},\"laneWidth\":10554,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":10,\"offset\":{\"xy\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"mergePoint\"],\"disabled\":[\"transitStopOnLeft\",\"bikeBoxInFront\",\"doNotBlock\"],\"enabled\":[\"mergingLaneLeft\",\"mergingLaneRight\"],\"data\":[{\"laneCrownPointCenter\":91},{\"laneCrownPointLeft\":-60},{\"laneCrownPointLeft\":-118}],\"dWidth\":-80,\"dElevation\":-211}},{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"hydrantPresent\",\"roundedCapStyleA\",\"roundedCapStyleB\"],\"disabled\":[\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnRight\",\"curbOnLeft\"],\"data\":[{\"laneCrownPointCenter\":-3},{\"laneCrownPointCenter\":-23},{\"speedLimits\":[{\"type\":\"vehicleMinSpeed\",\"speed\":5260},{\"type\":\"maxSpeedInConstructionZone\",\"speed\":7676}]}],\"dWidth\":-98,\"dElevation\":-300}},{\"delta\":{\"node-XY5\":{\"x\":6552,\"y\":-7382}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"stopLine\",\"reserved\",\"roundedCapStyleB\"],\"disabled\":[\"curbOnLeft\",\"turnOutPointOnRight\",\"whiteLine\",\"curbOnRight\"],\"enabled\":[\"sharedWithTrackedVehicle\",\"audibleSignalingPresent\",\"headInParking\"],\"data\":[{\"laneCrownPointCenter\":-7},{\"laneAngle\":68},{\"laneCrownPointLeft\":-39}],\"dWidth\":287,\"dElevation\":510}},{\"delta\":{\"node-XY1\":{\"x\":-310,\"y\":-500}},\"attributes\":{\"localNode\":[\"roundedCapStyleA\"],\"disabled\":[\"timeRestrictionsOnParking\",\"reserved\",\"parallelParking\",\"midBlockCurbPresent\"],\"enabled\":[\"transitStopOnRight\",\"whiteLine\",\"taperToCenterLine\",\"adjacentParkingOnLeft\",\"timeRestrictionsOnParking\"],\"data\":[{\"laneAngle\":-59},{\"laneCrownPointCenter\":105},{\"laneCrownPointCenter\":25},{\"speedLimits\":[{\"type\":\"vehicleNightMaxSpeed\",\"speed\":2245},{\"type\":\"vehicleMaxSpeed\",\"speed\":1700}]},{\"speedLimits\":[{\"type\":\"maxSpeedInSchoolZone\",\"speed\":7839},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":1190},{\"type\":\"truckMaxSpeed\",\"speed\":3947}]}],\"dWidth\":497,\"dElevation\":-208}},{\"delta\":{\"node-LatLon\":{\"lon\":-1625296958,\"lat\":501091223}},\"attributes\":{\"localNode\":[\"downstreamStartNode\",\"downstreamStopLine\",\"safeIsland\"],\"disabled\":[\"adjacentParkingOnLeft\",\"partialCurbIntrusion\",\"taperToRight\"],\"enabled\":[\"unEvenPavementPresent\",\"adjacentParkingOnRight\"],\"data\":[{\"laneCrownPointCenter\":86}],\"dWidth\":-90,\"dElevation\":131}}]}}}}},{\"name\":\"IA5S\",\"id\":{\"region\":48039,\"id\":14622},\"anchor\":{\"lat\":419808681,\"long\":-1470200813,\"elevation\":37213},\"laneWidth\":25845,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":true,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":25719,\"circle\":{\"center\":{\"lat\":-666313075,\"long\":639822734,\"elevation\":29597},\"radius\":1325,\"units\":\"foot\"}}}}],\"doNotUse3\":11,\"doNotUse4\":27,\"content\":{\"speedLimit\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"IA\"},{\"doNotUse1\":18,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":889823043,\"long\":-537303585,\"elevation\":29359},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":1652,\"startTime\":115878,\"durationTime\":7970,\"priority\":6,\"doNotUse2\":27,\"regions\":[{\"name\":\"I\",\"id\":{\"region\":26015,\"id\":40525},\"anchor\":{\"lat\":112058765,\"long\":1125609019,\"elevation\":54648},\"laneWidth\":31409,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":733403986,\"long\":1001009347,\"elevation\":23252},\"laneWidth\":14952,\"directionality\":\"unavailable\",\"nodeList\":{\"computed\":{\"referenceLaneId\":188,\"offsetXaxis\":{\"large\":-8154},\"offsetYaxis\":{\"large\":-28485},\"rotateXY\":224,\"scaleXaxis\":32,\"scaleYaxis\":1787}}}}}}}],\"doNotUse3\":14,\"doNotUse4\":21,\"content\":{\"exitService\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"I\"}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation\"}}";
+
+ // Has a different payload ID. Should be allowed through
+ String inputTim4 = "{\"metadata\":{\"logFileName\":\"\",\"recordType\":\"timMsg\",\"securityResultCode\":\"success\",\"receivedMessageDetails\":{\"rxSource\":\"NA\"},\"payloadType\":\"us.dot.its.jpo.ode.model.OdeTimPayload\",\"serialId\":{\"streamId\":\"b2d15f2d-7461-4083-b3df-b4efadab4d17\",\"bundleSize\":1,\"bundleId\":0,\"recordId\":0,\"serialNumber\":0},\"odeReceivedAt\":\"2025-02-01T01:20:45.739Z\",\"schemaVersion\":8,\"maxDurationTime\":0,\"recordGeneratedAt\":\"\",\"recordGeneratedBy\":\"RSU\",\"sanitized\":false,\"odePacketID\":\"\",\"odeTimStartDateTime\":\"\",\"asn1\":\"001F83A175D472274F43544554205354520A4C16B18193D0D1F9CDF54733FB1BFC0C983FCFC48D24FF97A474B8A754A9112A6F690200192EFCB5FF96D90FA32D4E83FC0C9830B5F5FC150A5059C545235AC20227C697080018815F84759CB3BF452C850424643A30E028544E9C511560A9DD8C2629F0D4470DBB3DDB4316096FC100800809BC746A108C8F26FC4C3208DA0E61091B7429182D3BFC0C98359EA8B4B454C16E606F037AE007A1CDE32000152E6C0ECDF612A90558D403FC049BF003734AC1C240EC930B39E850A7990A808008C033EFC47606FDDFA252B4A9942280C1020C9D818700EC4B4A76680C001D9F981240013111914408214602F8173D850A0D48F09F5D75264929260B5A7D27260B5A65260B56744F43999104E394B5204FF09260B5A7D3E32C5F74A0DB09EA975B8C1724DC92D9201005800092D84A89EF67BC1B27429C710979A5FE0E4C16B4F5EE874A08F2404C40AA60E2A09E79F91602003E5DB0AA9B32A2E0A6F36507F829305ACEE93E6B134C1CCC3C2EF3FA5CB5D02ECE000142002950BD8FB7D02D26BB6CAFCB848BE4A9260B5A7D29260B5A7D19D28125C17566972EA98F7172471344010153D0C21C1D69E158731BFC1C982D69E2E4FEDB544A012D60EDDB5D7569995CCC001CB02000CB8B449E02D39DB1072106F80B79BFC14982D666D178E4A198A3579B12B09915D01723B0000A10002A973AEAF40B82284427D9124DFE024F9230F8DD6AD73490518F80A3B259CF3FC40014001266976FBC88CB08E20EE8AD087EC16463A2B7AC5E62CB83FC9C830B7275F28A3128CDB2491AFF05260B580BDABD3249C784B718EFDC1906727B228001160002B10C89FAF5F0E9BA4F0AC74920F4947402561EBFB6201930424BF9E8112A39CA22519425D8E01001A7A1E0222723B864CB17F849305AD3E92E6884164E2CE7F0A6BD84FE4E38949D300081A01A290029F8111120048308876C910829B04B5148014FC9621814460542FAA24A460FBF82D2CF1A8CE66032A7E6A0807028A04283228610217947C12CE3FFF20CA031F809A2007D242408F0B4510F23D2A2646294D48A41F4F8494C87B58CCFE2983829A707069C17A4BBF23992859B3A528C03ACD3506FF07260B5A7BBA7391E53AAABAA44EA1584A857727A910002C0020391DD0DEDC78D916CBD8D839D52DABDB084919305C975AABA210D2D0CDF7A0ABC1000D3D0D9D071298F916D83FC049B2CFCF26A78A5951B5CC28075CAF1EAC780042808048EB0ADE229537A0161356A3A68175E5809621740382083BEDD5810921240\",\"originIp\":\"172.20.0.1\"},\"payload\":{\"data\":{\"msgCnt\":93,\"timeStamp\":291367,\"packetID\":\"4F4354455420535453\",\"urlB\":\"IA5\",\"dataFrames\":[{\"doNotUse1\":0,\"frameType\":\"commercialSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":1150,\"startTime\":473045,\"durationTime\":3687,\"priority\":7,\"doNotUse2\":22,\"regions\":[{\"name\":\"IA\",\"id\":{\"region\":64764,\"id\":18642},\"anchor\":{\"lat\":172032029,\"long\":-1025506517,\"elevation\":13386},\"laneWidth\":19949,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":9,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":252,\"offsetXaxis\":{\"large\":-5120},\"offsetYaxis\":{\"small\":-585},\"rotateXY\":8692,\"scaleXaxis\":-422,\"scaleYaxis\":464}}}}}},{\"name\":\"IA\",\"id\":{\"region\":2911,\"id\":24513},\"anchor\":{\"lat\":217001329,\"long\":-436271951,\"elevation\":28809},\"laneWidth\":30930,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":8,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL4\":{\"lon\":115258,\"lat\":80231}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"hydrantPresent\",\"mergePoint\",\"divergePoint\",\"reserved\"],\"disabled\":[\"transitStopOnRight\",\"adaptiveTimingPresent\",\"loadingzoneOnLeft\",\"costToPark\"],\"enabled\":[\"curbOnLeft\"],\"data\":[{\"speedLimits\":[{\"type\":\"truckNightMaxSpeed\",\"speed\":6769},{\"type\":\"truckMaxSpeed\",\"speed\":4438},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":2679},{\"type\":\"vehiclesWithTrailersNightMaxSpeed\",\"speed\":3110},{\"type\":\"vehicleMaxSpeed\",\"speed\":1987}]}],\"dWidth\":-188,\"dElevation\":-61}},{\"delta\":{\"node-LL6\":{\"lon\":5893850,\"lat\":-6770613}},\"attributes\":{\"localNode\":[\"closedToTraffic\"],\"disabled\":[\"bikeBoxInFront\"],\"enabled\":[\"mergingLaneRight\"],\"data\":[{\"laneCrownPointLeft\":-17}],\"dWidth\":-396,\"dElevation\":-88}},{\"delta\":{\"node-LL1\":{\"lon\":-924,\"lat\":-109}},\"attributes\":{\"localNode\":[\"downstreamStopLine\",\"roundedCapStyleB\"],\"disabled\":[\"whiteLine\",\"partialCurbIntrusion\"],\"enabled\":[\"loadingzoneOnLeft\",\"audibleSignalingPresent\",\"freeParking\"],\"data\":[{\"laneCrownPointCenter\":55},{\"laneAngle\":-98}],\"dWidth\":-319,\"dElevation\":-89}}]}}}}},{\"name\":\"IA\",\"id\":{\"region\":23018,\"id\":35659},\"anchor\":{\"lat\":-544509288,\"long\":-1334375239,\"elevation\":-3608},\"laneWidth\":14780,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":true,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":5,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":108,\"offsetXaxis\":{\"small\":-1574},\"offsetYaxis\":{\"large\":-635},\"rotateXY\":21792,\"scaleXaxis\":689,\"scaleYaxis\":640}}}}}},{\"name\":\"I\",\"id\":{\"region\":32256,\"id\":28265},\"anchor\":{\"lat\":725366646,\"long\":-566506763,\"elevation\":6227},\"laneWidth\":26178,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":1,\"offset\":{\"ll\":{\"nodes\":[{\"delta\":{\"node-LL5\":{\"lon\":2030663,\"lat\":-517129}},\"attributes\":{\"localNode\":[\"safeIsland\",\"hydrantPresent\",\"curbPresentAtStepOff\"],\"disabled\":[\"sharedWithTrackedVehicle\",\"transitStopOnLeft\",\"headInParking\",\"audibleSignalingPresent\"],\"enabled\":[\"doNotBlock\",\"mergingLaneLeft\"],\"data\":[{\"laneCrownPointRight\":48},{\"laneCrownPointRight\":-114}],\"dWidth\":-505,\"dElevation\":-119}},{\"delta\":{\"node-LL6\":{\"lon\":-5645920,\"lat\":-5242762}},\"attributes\":{\"localNode\":[\"reserved\",\"safeIsland\",\"mergePoint\"],\"disabled\":[\"turnOutPointOnLeft\"],\"enabled\":[\"timeRestrictionsOnParking\",\"adaptiveTimingPresent\",\"turnOutPointOnRight\",\"bikeBoxInFront\"],\"data\":[{\"laneCrownPointCenter\":-58},{\"pathEndPointAngle\":-55},{\"pathEndPointAngle\":-58}],\"dWidth\":472,\"dElevation\":-190}}]}}}}}],\"doNotUse3\":16,\"doNotUse4\":13,\"content\":{\"genericSign\":[{\"item\":{\"itis\":61599}},{\"item\":{\"itis\":47850}},{\"item\":{\"itis\":39204}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5S\"}}]},\"url\":\"IA5\"},{\"doNotUse1\":7,\"frameType\":\"roadSignage\",\"msgId\":{\"furtherInfoID\":\"4F43\"},\"startYear\":2457,\"startTime\":66787,\"durationTime\":19034,\"priority\":4,\"doNotUse2\":16,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":61846,\"id\":12218},\"anchor\":{\"lat\":202451669,\"long\":-1016248785,\"elevation\":14777},\"laneWidth\":4825,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":true,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100meters\",\"laneWidth\":23305,\"circle\":{\"center\":{\"lat\":257084126,\"long\":-1572221105,\"elevation\":10372},\"radius\":3021,\"units\":\"cm2-5\"}}}},{\"name\":\"IA5S\",\"id\":{\"region\":44916,\"id\":14928},\"anchor\":{\"lat\":-391962488,\"long\":-1442690475,\"elevation\":975},\"laneWidth\":8081,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":15,\"offset\":{\"xy\":{\"computed\":{\"referenceLaneId\":216,\"offsetXaxis\":{\"small\":682},\"offsetYaxis\":{\"large\":-6571},\"rotateXY\":11786,\"scaleXaxis\":-269,\"scaleYaxis\":-432}}}}}},{\"name\":\"IA5\",\"id\":{\"region\":15268,\"id\":63916},\"anchor\":{\"lat\":-14883901,\"long\":1470459302,\"elevation\":47965},\"laneWidth\":374,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor100000meters\",\"area\":{\"circle\":{\"center\":{\"lat\":223434207,\"long\":-714422034,\"elevation\":41663},\"radius\":737,\"units\":\"cm2-5\"}}}}}],\"doNotUse3\":2,\"doNotUse4\":31,\"content\":{\"workZone\":[{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"text\":\"IA5St\"}},{\"item\":{\"itis\":52884}}]},\"url\":\"I\"},{\"doNotUse1\":16,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":604037802,\"long\":-124613998,\"elevation\":46289},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":true,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"guide\",\"crc\":\"4F43\"}},\"startYear\":135,\"startTime\":30119,\"durationTime\":17072,\"priority\":7,\"doNotUse2\":6,\"regions\":[{\"name\":\"IA5S\",\"id\":{\"region\":35731,\"id\":64365},\"anchor\":{\"lat\":251341270,\"long\":-1550588968,\"elevation\":18073},\"laneWidth\":19174,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":true},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":19339,\"circle\":{\"center\":{\"lat\":-590142898,\"long\":192563845,\"elevation\":3040},\"radius\":734,\"units\":\"meter\"}}}},{\"name\":\"IA5\",\"id\":{\"region\":13160,\"id\":48242},\"anchor\":{\"lat\":227302831,\"long\":-891580621,\"elevation\":7072},\"laneWidth\":5923,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":true,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":true,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"area\":{\"circle\":{\"center\":{\"lat\":368610426,\"long\":-1703460317,\"elevation\":1004},\"radius\":2194,\"units\":\"meter\"}}}}},{\"name\":\"I\",\"id\":{\"region\":58508,\"id\":15927},\"anchor\":{\"lat\":892488592,\"long\":-431640924,\"elevation\":41561},\"laneWidth\":26527,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":true,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"regionPointSet\":{\"anchor\":{\"lat\":-113602543,\"long\":717746718,\"elevation\":49498},\"scale\":1,\"nodeList\":[{\"xOffset\":27670,\"yOffset\":-14790,\"zOffset\":-21638},{\"xOffset\":3020,\"yOffset\":-9872,\"zOffset\":-109},{\"xOffset\":-24382,\"yOffset\":23709,\"zOffset\":-862},{\"xOffset\":-26476,\"yOffset\":-6439,\"zOffset\":-23411}]}}}}},{\"name\":\"IA5\",\"id\":{\"region\":379,\"id\":22438},\"anchor\":{\"lat\":-281093797,\"long\":556669965,\"elevation\":29497},\"laneWidth\":7880,\"directionality\":\"reverse\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":true,\"from337-5to360-0degrees\":false},\"extent\":\"useFor500000meters\",\"laneWidth\":2148,\"circle\":{\"center\":{\"lat\":163173661,\"long\":-872411303,\"elevation\":55588},\"radius\":489,\"units\":\"cm2-5\"}}}}],\"doNotUse3\":8,\"doNotUse4\":29,\"content\":{\"advisory\":[{\"item\":{\"itis\":44093}},{\"item\":{\"itis\":65240}},{\"item\":{\"text\":\"IA\"}}]},\"url\":\"I\"},{\"doNotUse1\":31,\"frameType\":\"advisory\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":-864002503,\"long\":-654286715,\"elevation\":43804},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":true,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":3076,\"startTime\":282183,\"durationTime\":14436,\"priority\":6,\"doNotUse2\":11,\"regions\":[{\"name\":\"IA5St\",\"id\":{\"region\":11880,\"id\":33814},\"anchor\":{\"lat\":51295938,\"long\":799818234,\"elevation\":10466},\"laneWidth\":10554,\"directionality\":\"forward\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"path\":{\"scale\":10,\"offset\":{\"xy\":{\"nodes\":[{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"mergePoint\"],\"disabled\":[\"transitStopOnLeft\",\"bikeBoxInFront\",\"doNotBlock\"],\"enabled\":[\"mergingLaneLeft\",\"mergingLaneRight\"],\"data\":[{\"laneCrownPointCenter\":91},{\"laneCrownPointLeft\":-60},{\"laneCrownPointLeft\":-118}],\"dWidth\":-80,\"dElevation\":-211}},{\"delta\":{\"node-XY1\":{\"x\":144,\"y\":-502}},\"attributes\":{\"localNode\":[\"hydrantPresent\",\"roundedCapStyleA\",\"roundedCapStyleB\"],\"disabled\":[\"turnOutPointOnRight\"],\"enabled\":[\"adjacentParkingOnRight\",\"curbOnLeft\"],\"data\":[{\"laneCrownPointCenter\":-3},{\"laneCrownPointCenter\":-23},{\"speedLimits\":[{\"type\":\"vehicleMinSpeed\",\"speed\":5260},{\"type\":\"maxSpeedInConstructionZone\",\"speed\":7676}]}],\"dWidth\":-98,\"dElevation\":-300}},{\"delta\":{\"node-XY5\":{\"x\":6552,\"y\":-7382}},\"attributes\":{\"localNode\":[\"curbPresentAtStepOff\",\"stopLine\",\"reserved\",\"roundedCapStyleB\"],\"disabled\":[\"curbOnLeft\",\"turnOutPointOnRight\",\"whiteLine\",\"curbOnRight\"],\"enabled\":[\"sharedWithTrackedVehicle\",\"audibleSignalingPresent\",\"headInParking\"],\"data\":[{\"laneCrownPointCenter\":-7},{\"laneAngle\":68},{\"laneCrownPointLeft\":-39}],\"dWidth\":287,\"dElevation\":510}},{\"delta\":{\"node-XY1\":{\"x\":-310,\"y\":-500}},\"attributes\":{\"localNode\":[\"roundedCapStyleA\"],\"disabled\":[\"timeRestrictionsOnParking\",\"reserved\",\"parallelParking\",\"midBlockCurbPresent\"],\"enabled\":[\"transitStopOnRight\",\"whiteLine\",\"taperToCenterLine\",\"adjacentParkingOnLeft\",\"timeRestrictionsOnParking\"],\"data\":[{\"laneAngle\":-59},{\"laneCrownPointCenter\":105},{\"laneCrownPointCenter\":25},{\"speedLimits\":[{\"type\":\"vehicleNightMaxSpeed\",\"speed\":2245},{\"type\":\"vehicleMaxSpeed\",\"speed\":1700}]},{\"speedLimits\":[{\"type\":\"maxSpeedInSchoolZone\",\"speed\":7839},{\"type\":\"maxSpeedInSchoolZone\",\"speed\":1190},{\"type\":\"truckMaxSpeed\",\"speed\":3947}]}],\"dWidth\":497,\"dElevation\":-208}},{\"delta\":{\"node-LatLon\":{\"lon\":-1625296958,\"lat\":501091223}},\"attributes\":{\"localNode\":[\"downstreamStartNode\",\"downstreamStopLine\",\"safeIsland\"],\"disabled\":[\"adjacentParkingOnLeft\",\"partialCurbIntrusion\",\"taperToRight\"],\"enabled\":[\"unEvenPavementPresent\",\"adjacentParkingOnRight\"],\"data\":[{\"laneCrownPointCenter\":86}],\"dWidth\":-90,\"dElevation\":131}}]}}}}},{\"name\":\"IA5S\",\"id\":{\"region\":48039,\"id\":14622},\"anchor\":{\"lat\":419808681,\"long\":-1470200813,\"elevation\":37213},\"laneWidth\":25845,\"directionality\":\"unavailable\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":true,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"geometry\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":true,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor3meters\",\"laneWidth\":25719,\"circle\":{\"center\":{\"lat\":-666313075,\"long\":639822734,\"elevation\":29597},\"radius\":1325,\"units\":\"foot\"}}}}],\"doNotUse3\":11,\"doNotUse4\":27,\"content\":{\"speedLimit\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"IA\"},{\"doNotUse1\":18,\"frameType\":\"roadSignage\",\"msgId\":{\"roadSignID\":{\"position\":{\"lat\":889823043,\"long\":-537303585,\"elevation\":29359},\"viewAngle\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":true,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"mutcdCode\":\"maintenance\",\"crc\":\"4F43\"}},\"startYear\":1652,\"startTime\":115878,\"durationTime\":7970,\"priority\":6,\"doNotUse2\":27,\"regions\":[{\"name\":\"I\",\"id\":{\"region\":26015,\"id\":40525},\"anchor\":{\"lat\":112058765,\"long\":1125609019,\"elevation\":54648},\"laneWidth\":31409,\"directionality\":\"both\",\"closedPath\":true,\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":false,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":true,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"description\":{\"oldRegion\":{\"direction\":{\"from000-0to022-5degrees\":false,\"from022-5to045-0degrees\":false,\"from045-0to067-5degrees\":false,\"from067-5to090-0degrees\":false,\"from090-0to112-5degrees\":false,\"from112-5to135-0degrees\":false,\"from135-0to157-5degrees\":false,\"from157-5to180-0degrees\":true,\"from180-0to202-5degrees\":false,\"from202-5to225-0degrees\":false,\"from225-0to247-5degrees\":false,\"from247-5to270-0degrees\":false,\"from270-0to292-5degrees\":false,\"from292-5to315-0degrees\":false,\"from315-0to337-5degrees\":false,\"from337-5to360-0degrees\":false},\"extent\":\"useFor50000meters\",\"area\":{\"shapePointSet\":{\"anchor\":{\"lat\":733403986,\"long\":1001009347,\"elevation\":23252},\"laneWidth\":14952,\"directionality\":\"unavailable\",\"nodeList\":{\"computed\":{\"referenceLaneId\":188,\"offsetXaxis\":{\"large\":-8154},\"offsetYaxis\":{\"large\":-28485},\"rotateXY\":224,\"scaleXaxis\":32,\"scaleYaxis\":1787}}}}}}}],\"doNotUse3\":14,\"doNotUse4\":21,\"content\":{\"exitService\":[{\"item\":{\"text\":\"I\"}}]},\"url\":\"I\"}]},\"dataType\":\"us.dot.its.jpo.ode.plugin.j2735.travelerinformation.TravelerInformation\"}}";
+
+ @Autowired
+ DeduplicatorProperties props;
+
+ @Test
+ public void testTopology() {
+
+ props = new DeduplicatorProperties();
+ props.setKafkaTopicOdeTimJson(inputTopic);
+ props.setKafkaTopicDeduplicatedOdeTimJson(outputTopic);
+
+ TimDeduplicatorTopology TimDeduplicatorTopology = new TimDeduplicatorTopology(props, null);
+
+ Topology topology = TimDeduplicatorTopology.buildTopology();
+ objectMapper.registerModule(new JavaTimeModule());
+
+ try (TopologyTestDriver driver = new TopologyTestDriver(topology)) {
+
+
+ TestInputTopic inputTimData = driver.createInputTopic(
+ inputTopic,
+ Serdes.Void().serializer(),
+ Serdes.String().serializer());
+
+
+ TestOutputTopic outputTimData = driver.createOutputTopic(
+ outputTopic,
+ Serdes.String().deserializer(),
+ Serdes.String().deserializer());
+
+ inputTimData.pipeInput(null, inputTim1);
+ inputTimData.pipeInput(null, inputTim2);
+ inputTimData.pipeInput(null, inputTim3);
+ inputTimData.pipeInput(null, inputTim4);
+
+ List> timDeduplicatedResults = outputTimData.readKeyValuesToList();
+
+ // validate that only 3 messages make it through
+ assertEquals(3, timDeduplicatedResults.size());
+ inputTim1 = inputTim1.strip();
+
+ assertEquals(inputTim1.replace(" ", ""), timDeduplicatedResults.get(0).value.replace(" ", ""));
+ assertEquals(inputTim3.replace(" ", ""), timDeduplicatedResults.get(1).value.replace(" ", ""));
+ assertEquals(inputTim4.replace(" ", ""), timDeduplicatedResults.get(2).value.replace(" ", ""));
+
+ }catch(Exception e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/jpo-deduplicator/src/test/resources/application-testConfig.yaml b/jpo-deduplicator/src/test/resources/application-testConfig.yaml
new file mode 100644
index 0000000..4f102d0
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/application-testConfig.yaml
@@ -0,0 +1 @@
+spring.kafka.bootstrap-servers: localhost:10093
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/map/sample.map-different.json b/jpo-deduplicator/src/test/resources/json/map/sample.map-different.json
new file mode 100644
index 0000000..9af4acc
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/map/sample.map-different.json
@@ -0,0 +1,1524 @@
+{
+ "metadata": {
+ "logFileName": "",
+ "recordType": "mapTx",
+ "securityResultCode": "success",
+ "receivedMessageDetails": {
+ "rxSource": "NA"
+ },
+ "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload",
+ "serialId": {
+ "streamId": "35ecef57-56ce-44ca-beca-16279d7471e1",
+ "bundleSize": 1,
+ "bundleId": 0,
+ "recordId": 0,
+ "serialNumber": 0
+ },
+ "odeReceivedAt": "2025-01-31T00:00:00.000Z",
+ "schemaVersion": 8,
+ "maxDurationTime": 0,
+ "recordGeneratedAt": "",
+ "recordGeneratedBy": "RSU",
+ "sanitized": false,
+ "odePacketID": "",
+ "odeTimStartDateTime": "",
+ "asn1": "0012820038033000205EA60D4D383C3B2CA7114251C802DC1C580C68000002000195D3B9FDA4ACED70318D6FAE8119027D9ACA8F03C4050535DEF6012C0A0A0586200020096029A000001C000A574B07DF62B39E40D4B5B99604D809F66B34DC0B5014145673C82726B69A414D013D857A7C81141587C000200AC350001008B0211000000800026BDF34287036E50516257A64D1B0FE52B3C04FB3620E259C809E20581C0003009603A200000100004D7A89855A02828B11C9306ED882C9644027D9B11292E5E04F102C120001804B0255000000400036BFAC42D4814145805684DE2C39D4A22B61F9E55D409F66C3F6CABA813C40B0F40001012C0A540000010000DB01D10B4E050516005E1279B0F892AC804FB361F42566009F66C3B449EC013D80B0E4000101100B6200000001B08A50C0805051601FE042040318800000006C2D042C3014145806E80FD100D6200000000B0E0B09D6D80568102028284039C800000002C42E3FA6960805FE4C403DC800000002C3E33EAA160779FF30B0085000000800032C07ABCE5B5ED2DC8D809EC6B88CABE88139CD6EFD53BB02761ADDC4A69E04E70AC32000080561700004045802280000050001960A91E72DAF618E3A804F635C3D55F2409CE6B761A9B2013B0D6F02536F02738561B000040230F2000210042200000000AECF8F5C257FAA7EBF10032200000000AF07CF58857FAF7ED00142857ED47FFA10072200000001AF1150904050A15FB9A000040208800000006BC4AC2F00142857EE080002C0A3400000200019AFB5D1346050A35FFA6177C0A0A2BFE64464B5FD921F600A0A6BF14443981428D7CF6891302851AF5E11142050A35EED218340A0A058EC00020096049A0000004000ED7C1B896902851AFFE90DCE050535FE5E2E3C0A0A6BFB3C26781414D7E5C883402829AF9911096050A35F57A14CC0A142BE86C25D35F2F610940A0A218412000AC7A000100C60E40004581668000002000135FB8226D80A146BFF1C7C401414D7F3C878202829AFB531352050A02C590001C04B030D000000400036C00BC4E681428D801789A302828AFF8D0F76D7F0E877C02829AFC950CA4050502C554001C0440350800000006C0DD44F88142858000814D100E4200000001B06A713CA050536000205480A0A2C197400000200001B079CED3004F135FF1113200A3205874000400960D3A00000100000D8234765D027B1AFFF08A14051402C360002004B06DD000000400006C0653B22013D8D800A4518028A0160C80006025838E8000002000035FDB1D84C09EC6C003BA14814140B0540003012C187400000080011B13F6EDB804F115FA6DFC10AFC94FC6A57EE07DCE2BFA7BED3B5FFCD72E80A1E018C9000082DA50180060282814420202000",
+ "mapSource": "RSU",
+ "originIp": "8.8.8.8"
+ },
+ "payload": {
+ "data": {
+ "msgIssueRevision": 3,
+ "layerType": "intersectionData",
+ "layerID": 0,
+ "intersections": {
+ "intersectionGeometry": [
+ {
+ "id": {
+ "id": 12115
+ },
+ "revision": 3,
+ "refPoint": {
+ "latitude": 39.5531067,
+ "longitude": -105.0853565,
+ "elevation": 1684.0
+ },
+ "laneWidth": 366,
+ "laneSet": {
+ "GenericLane": [
+ {
+ "laneID": 6,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2834,
+ "y": -151
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6293,
+ "y": 396
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4178,
+ "y": 281
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6841,
+ "y": 482
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2115,
+ "y": 75
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 5,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2896,
+ "y": -522
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6340,
+ "y": 425
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4507,
+ "y": 310
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6501,
+ "y": 362
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6340,
+ "y": 626
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4812,
+ "y": 666
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1412,
+ "y": 276
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 15,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ },
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 2
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 8,
+ "ingressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1050,
+ "y": 1294
+ }
+ },
+ "attributes": {
+ "dWidth": 370,
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2398,
+ "y": 6452
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2034,
+ "y": 5534
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2104,
+ "y": 5746
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 3,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 7,
+ "ingressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1399,
+ "y": 1370
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2276,
+ "y": 6199
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2092,
+ "y": 5700
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2196,
+ "y": 5935
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 4,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 9,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -168,
+ "y": 1449
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 86,
+ "y": 1246
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1850,
+ "y": 5189
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2023,
+ "y": 5493
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2029,
+ "y": 5493
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 15,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 10,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 232,
+ "y": 1447
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 23,
+ "y": 1182
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1988,
+ "y": 5476
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2000,
+ "y": 5528
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1896,
+ "y": 5080
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 14,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 11,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1106,
+ "y": 1540
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 127,
+ "y": 264
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 12,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1440,
+ "y": 1414
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 110,
+ "y": 253
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 13,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1797,
+ "y": 1259
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 86,
+ "y": 258
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 14,
+ "egressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2140,
+ "y": -179
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 513,
+ "y": -109
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 15,
+ "egressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1990,
+ "y": -684
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 478,
+ "y": -52
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 2,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 245,
+ "y": -1589
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1205,
+ "y": -3530
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -3815,
+ "y": -10287
+ }
+ },
+ "attributes": {
+ "dElevation": -50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4355,
+ "y": -11333
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4382,
+ "y": -11441
+ }
+ },
+ "attributes": {
+ "dElevation": -50
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ },
+ {
+ "connectingLane": {
+ "lane": 11,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 2
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 1,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 676,
+ "y": -1589
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1268,
+ "y": -3628
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -3851,
+ "y": -10295
+ }
+ },
+ "attributes": {
+ "dElevation": -50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4413,
+ "y": -11420
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -4350,
+ "y": -11409
+ }
+ },
+ "attributes": {
+ "dElevation": -50
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ },
+ {
+ "connectingLane": {
+ "lane": 15,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 2
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 4,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2436,
+ "y": -1311
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -86,
+ "y": -321
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 3,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1986,
+ "y": -1340
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -81,
+ "y": -304
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP"
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/map/sample.map-reference-1-hour-later.json b/jpo-deduplicator/src/test/resources/json/map/sample.map-reference-1-hour-later.json
new file mode 100644
index 0000000..e7df02d
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/map/sample.map-reference-1-hour-later.json
@@ -0,0 +1,2814 @@
+{
+ "metadata": {
+ "logFileName": "",
+ "recordType": "mapTx",
+ "securityResultCode": "success",
+ "receivedMessageDetails": {
+ "rxSource": "NA"
+ },
+ "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload",
+ "serialId": {
+ "streamId": "d963d421-fba0-4b21-b991-229e8d3bf9c1",
+ "bundleSize": 1,
+ "bundleId": 0,
+ "recordId": 0,
+ "serialNumber": 0
+ },
+ "odeReceivedAt": "2025-01-31T01:01:00.000Z",
+ "schemaVersion": 8,
+ "maxDurationTime": 0,
+ "recordGeneratedAt": "",
+ "recordGeneratedBy": "RSU",
+ "sanitized": false,
+ "odePacketID": "",
+ "odeTimStartDateTime": "",
+ "asn1": "001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E",
+ "mapSource": "RSU",
+ "originIp": "8.8.8.8"
+ },
+ "payload": {
+ "data": {
+ "msgIssueRevision": 0,
+ "layerType": "intersectionData",
+ "layerID": 0,
+ "intersections": {
+ "intersectionGeometry": [
+ {
+ "id": {
+ "id": 12110
+ },
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677.0
+ },
+ "laneWidth": 366,
+ "laneSet": {
+ "GenericLane": [
+ {
+ "laneID": 2,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2225,
+ "y": 808
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 10517,
+ "y": -161
+ }
+ },
+ "attributes": {
+ "dElevation": -60
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2769,
+ "y": 112
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6142,
+ "y": -180
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6636,
+ "y": -12
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3804,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 3,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2222,
+ "y": 515
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2933,
+ "y": -82
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6259,
+ "y": -85
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3416,
+ "y": -98
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6867,
+ "y": -39
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2657,
+ "y": -55
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 4259,
+ "y": 67
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3481,
+ "y": 0
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 1,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2215,
+ "y": 1218
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 10451,
+ "y": -223
+ }
+ },
+ "attributes": {
+ "dElevation": -70
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1852,
+ "y": -108
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 4,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2213,
+ "y": -124
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 7187,
+ "y": 20
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 541,
+ "y": 40
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1298,
+ "y": 229
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 6,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2267,
+ "y": -1019
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 365,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 5,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2267,
+ "y": -662
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 338,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 7,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2294,
+ "y": -1463
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 365,
+ "y": 27
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 12,
+ "egressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -952,
+ "y": -1898
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": -377
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 13,
+ "egressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1440,
+ "y": -1898
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 7,
+ "y": -390
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 10,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 705,
+ "y": -1919
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1,
+ "y": -7515
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -41,
+ "y": -5272
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -17,
+ "y": -11337
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 17,
+ "y": -5938
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 9,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1090,
+ "y": -1930
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 9,
+ "y": -4764
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -20,
+ "y": -6402
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -34,
+ "y": -7953
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 16,
+ "y": -10940
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 11,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 350,
+ "y": -1925
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -32,
+ "y": -6698
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 156,
+ "y": -2616
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 8,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1557,
+ "y": -1956
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -101,
+ "y": -1956
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -5,
+ "y": -7393
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -121,
+ "y": -1636
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 15,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2405,
+ "y": -1018
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -9339,
+ "y": 26
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11895,
+ "y": -38
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -8814,
+ "y": 13
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 16,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2337,
+ "y": -656
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -12229,
+ "y": 15
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11362,
+ "y": -37
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6537,
+ "y": 1
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 17,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2338,
+ "y": -284
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -8892,
+ "y": -18
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11959,
+ "y": -2
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1564,
+ "y": -180
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 14,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2401,
+ "y": -1380
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -19947,
+ "y": 8
+ }
+ },
+ "attributes": {
+ "dElevation": 80
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -10108,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 18,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2264,
+ "y": 479
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -580,
+ "y": -14
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 19,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2257,
+ "y": 796
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -518,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 20,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2236,
+ "y": 1229
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -484,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 23,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -914,
+ "y": 1903
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 225,
+ "y": 12288
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 40,
+ "y": 9634
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 32,
+ "y": 8035
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 28
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 22,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1221,
+ "y": 1914
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 92,
+ "y": 10475
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 89,
+ "y": 11582
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 48,
+ "y": 7912
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 21,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1649,
+ "y": 1935
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 16,
+ "y": 3182
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 21,
+ "y": 5991
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 102,
+ "y": 4810
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 85,
+ "y": 11803
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 19,
+ "y": 4161
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 24,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -535,
+ "y": 1926
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 28,
+ "y": 4582
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 88,
+ "y": 3793
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -143,
+ "y": 1866
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 25,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -213,
+ "y": 1913
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 14,
+ "y": 4594
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -91,
+ "y": 2238
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 26,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 724,
+ "y": 1902
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 352
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 27,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1105,
+ "y": 1888
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 332
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 28,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1591,
+ "y": 1874
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -14,
+ "y": 346
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP"
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/map/sample.map-reference.json b/jpo-deduplicator/src/test/resources/json/map/sample.map-reference.json
new file mode 100644
index 0000000..e1a7a87
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/map/sample.map-reference.json
@@ -0,0 +1,2814 @@
+{
+ "metadata": {
+ "logFileName": "",
+ "recordType": "mapTx",
+ "securityResultCode": "success",
+ "receivedMessageDetails": {
+ "rxSource": "NA"
+ },
+ "payloadType": "us.dot.its.jpo.ode.model.OdeMapPayload",
+ "serialId": {
+ "streamId": "d963d421-fba0-4b21-b991-229e8d3bf9c1",
+ "bundleSize": 1,
+ "bundleId": 0,
+ "recordId": 0,
+ "serialNumber": 0
+ },
+ "odeReceivedAt": "2025-01-31T00:00:00.000Z",
+ "schemaVersion": 8,
+ "maxDurationTime": 0,
+ "recordGeneratedAt": "",
+ "recordGeneratedBy": "RSU",
+ "sanitized": false,
+ "odePacketID": "",
+ "odeTimStartDateTime": "",
+ "asn1": "001283C138003000205E9C014D3EAB092CA624B5518202DC3658042800000400023622C60CA009F66D48ABFAF81388D8AD18070027D9B2FFCFE9804F13667B1FFD009EC2C76E3FFC82C4E0001004B00C5000000800066C4574101813ECD8B757FAE027D9B30E6FF5604EC363561FE7809EC6CD69BFEC813C4D8A617FC9027D9B2147008604FB163666000016250000802580228000001000096229E1309B51A6FE4204DD361CF1FE5009F6018E1000096020A00000080004D88A57F84027D9B3827002804EC36087600A009F62C289407282C310001C0440188800000006C46DBE02813EC5816D800710052200000001B11B6FAD404FB16054A0000401C8800000006C47B3D24813EC5816D801B100C4200000000AF890F12C580007E87100D4200000008AF4C0F12C580077E7A2C0004000160002001CB028D000000800052C160BC40B5FFFD8A9409D86BFEBB5B40141457FEF53B76C008B467014145800080002BFFCBFFC82C6A0001804B024D000000800036C2213C3B013ECD80096D64027D9AFFD8CDFC04F635FF7983BC09F66C0082AA2014280B1B80006012C0B3400000100004B02BCF0F6D7FE065D602788B0138EB900B1240001012C083400000080009B0C2AF0B804FB15FE6DE171AFFF6C63E04EC15FE1DE670060E40002581EA8000004000135DA6DF0180A0A6ADC2C00D0143CD51897FDA028C8ABB25001A0B0680008012C105400000200009AEDBEFAE005053540EE003C0A326A9CF3FED8143C5667780010582C0004009608AA00000080004D76DE7EE402829ABA88FFDC050F354525FFF80A322BCF23FA602C690000C04B0395000000200016BB4FBD4E01414D3215800802940AB108FFF2030D2000110126200000001AEE5103BE050A15F6F1FFC8404D8800000006BB97C18E0142857DFA800010146200000001AEE89099A050A15F8720000B05DD000000800046BE3743B781428D80E1B00002879B00514B4404F63600827D8C09E22C000400015FFE6007016190000402582CE8000004000135ECEE1DE80A146C02E54758143CD8059AD3E027B1B00613DD004F102C360000804B055D000000200046BCC7C3C781428D80108C6E02829B002B2ECE050A16019A4B29B00AB5C3604F136004E410409EC018A10000960C3A00000080004D7DE9878602851B003923CC05053601623B440A0A6BFB8C3A5014140B0640005012C197400000100005AFE570EF2050A36003A47C80A0A6BFD2C45F014140B054000501101A8200000001B05A90EDC050535FFE605800A0A101B8200000001B08A30EC0050535FFE605300A0A101C8200000005B0C6F0EA4050515FFCA0568B0001000E",
+ "mapSource": "RSU",
+ "originIp": "8.8.8.8"
+ },
+ "payload": {
+ "data": {
+ "msgIssueRevision": 0,
+ "layerType": "intersectionData",
+ "layerID": 0,
+ "intersections": {
+ "intersectionGeometry": [
+ {
+ "id": {
+ "id": 12110
+ },
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677.0
+ },
+ "laneWidth": 366,
+ "laneSet": {
+ "GenericLane": [
+ {
+ "laneID": 2,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2225,
+ "y": 808
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 10517,
+ "y": -161
+ }
+ },
+ "attributes": {
+ "dElevation": -60
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2769,
+ "y": 112
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6142,
+ "y": -180
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6636,
+ "y": -12
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3804,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 3,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2222,
+ "y": 515
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2933,
+ "y": -82
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6259,
+ "y": -85
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3416,
+ "y": -98
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 6867,
+ "y": -39
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2657,
+ "y": -55
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 4259,
+ "y": 67
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 3481,
+ "y": 0
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 1,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2215,
+ "y": 1218
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 10451,
+ "y": -223
+ }
+ },
+ "attributes": {
+ "dElevation": -70
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1852,
+ "y": -108
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 4,
+ "ingressApproach": 1,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2213,
+ "y": -124
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 7187,
+ "y": 20
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 541,
+ "y": 40
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1298,
+ "y": 229
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 6,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2267,
+ "y": -1019
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 365,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 5,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2267,
+ "y": -662
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 338,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 7,
+ "egressApproach": 2,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 2294,
+ "y": -1463
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 365,
+ "y": 27
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 12,
+ "egressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -952,
+ "y": -1898
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": -377
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 13,
+ "egressApproach": 4,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1440,
+ "y": -1898
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 7,
+ "y": -390
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 10,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 705,
+ "y": -1919
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1,
+ "y": -7515
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -41,
+ "y": -5272
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -17,
+ "y": -11337
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 17,
+ "y": -5938
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 9,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1090,
+ "y": -1930
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 9,
+ "y": -4764
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -20,
+ "y": -6402
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -34,
+ "y": -7953
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 16,
+ "y": -10940
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 11,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 350,
+ "y": -1925
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -32,
+ "y": -6698
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 156,
+ "y": -2616
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 8,
+ "ingressApproach": 3,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1557,
+ "y": -1956
+ }
+ },
+ "attributes": {
+ "dElevation": -10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -101,
+ "y": -1956
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -5,
+ "y": -7393
+ }
+ },
+ "attributes": {
+ "dElevation": -40
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -121,
+ "y": -1636
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 15,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2405,
+ "y": -1018
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -9339,
+ "y": 26
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11895,
+ "y": -38
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -8814,
+ "y": 13
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 16,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2337,
+ "y": -656
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -12229,
+ "y": 15
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11362,
+ "y": -37
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -6537,
+ "y": 1
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 17,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2338,
+ "y": -284
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -8892,
+ "y": -18
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -11959,
+ "y": -2
+ }
+ },
+ "attributes": {
+ "dElevation": 50
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1564,
+ "y": -180
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 14,
+ "ingressApproach": 5,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2401,
+ "y": -1380
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -19947,
+ "y": 8
+ }
+ },
+ "attributes": {
+ "dElevation": 80
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -10108,
+ "y": -7
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 18,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2264,
+ "y": 479
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -580,
+ "y": -14
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 19,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2257,
+ "y": 796
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -518,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 20,
+ "egressApproach": 6,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -2236,
+ "y": 1229
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -484,
+ "y": 0
+ }
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 23,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -914,
+ "y": 1903
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 225,
+ "y": 12288
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 40,
+ "y": 9634
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 32,
+ "y": 8035
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 0
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 28
+ }
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 22,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1221,
+ "y": 1914
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 92,
+ "y": 10475
+ }
+ },
+ "attributes": {
+ "dElevation": 30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 89,
+ "y": 11582
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 48,
+ "y": 7912
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 21,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -1649,
+ "y": 1935
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 16,
+ "y": 3182
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 21,
+ "y": 5991
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 102,
+ "y": 4810
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 85,
+ "y": 11803
+ }
+ },
+ "attributes": {
+ "dElevation": -30
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 19,
+ "y": 4161
+ }
+ },
+ "attributes": {
+ "dElevation": -20
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 24,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -535,
+ "y": 1926
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 28,
+ "y": 4582
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 88,
+ "y": 3793
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -143,
+ "y": 1866
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 25,
+ "ingressApproach": 7,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": true,
+ "egressPath": false
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -213,
+ "y": 1913
+ }
+ },
+ "attributes": {
+ "dElevation": 20
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 14,
+ "y": 4594
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -91,
+ "y": 2238
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ },
+ "connectsTo": {
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 26,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 724,
+ "y": 1902
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 352
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 27,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1105,
+ "y": 1888
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -7,
+ "y": 332
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ }
+ ]
+ }
+ },
+ {
+ "laneID": 28,
+ "egressApproach": 8,
+ "laneAttributes": {
+ "directionalUse": {
+ "ingressPath": false,
+ "egressPath": true
+ },
+ "shareWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ }
+ },
+ "nodeList": {
+ "nodes": [
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 1591,
+ "y": 1874
+ }
+ },
+ "attributes": {
+ "dElevation": 10
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": -14,
+ "y": 346
+ }
+ }
+ },
+ {
+ "delta": {
+ "nodeXY6": {
+ "x": 0,
+ "y": 7
+ }
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "dataType": "us.dot.its.jpo.ode.plugin.j2735.J2735MAP"
+ }
+}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-different.json b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-different.json
new file mode 100644
index 0000000..d839175
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-different.json
@@ -0,0 +1,3443 @@
+{
+ "mapFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 2,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0899239,
+ 39.5953231
+ ],
+ [
+ -105.0896005,
+ 39.5953332
+ ],
+ [
+ -105.0888831,
+ 39.595317
+ ],
+ [
+ -105.088108,
+ 39.5953159
+ ],
+ [
+ -105.0876637,
+ 39.5953153
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2225,
+ 808
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 10517,
+ -161
+ ],
+ "delevation": -60
+ },
+ {
+ "delta": [
+ 2769,
+ 112
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6142,
+ -180
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 6636,
+ -12
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 3804,
+ -7
+ ]
+ }
+ ],
+ "laneId": 2,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 3,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0908101,
+ 39.5953039
+ ],
+ [
+ -105.0900791,
+ 39.5952962
+ ],
+ [
+ -105.0896801,
+ 39.5952874
+ ],
+ [
+ -105.0888781,
+ 39.5952839
+ ],
+ [
+ -105.0885678,
+ 39.5952789
+ ],
+ [
+ -105.0880704,
+ 39.5952849
+ ],
+ [
+ -105.0876638,
+ 39.5952849
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2222,
+ 515
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 2933,
+ -82
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6259,
+ -85
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 3416,
+ -98
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 6867,
+ -39
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 2657,
+ -55
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 4259,
+ 67
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 3481,
+ 0
+ ]
+ }
+ ],
+ "laneId": 3,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 1,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0899328,
+ 39.5953544
+ ],
+ [
+ -105.0897165,
+ 39.5953447
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2215,
+ 1218
+ ]
+ },
+ {
+ "delta": [
+ 10451,
+ -223
+ ],
+ "delevation": -70
+ },
+ {
+ "delta": [
+ 1852,
+ -108
+ ],
+ "delevation": -10
+ }
+ ],
+ "laneId": 1,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 4,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0903143,
+ 39.5952555
+ ],
+ [
+ -105.0902511,
+ 39.5952591
+ ],
+ [
+ -105.0900995,
+ 39.5952797
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2213,
+ -124
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 7187,
+ 20
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 541,
+ 40
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 1298,
+ 229
+ ]
+ }
+ ],
+ "laneId": 4,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 6,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5951732
+ ],
+ [
+ -105.0911048,
+ 39.5951738
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -1019
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 7
+ ]
+ }
+ ],
+ "laneId": 6,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 5,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5952053
+ ],
+ [
+ -105.0911079,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -662
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 338,
+ 0
+ ]
+ }
+ ],
+ "laneId": 5,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 7,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911443,
+ 39.5951332
+ ],
+ [
+ -105.0911017,
+ 39.5951356
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2294,
+ -1463
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 27
+ ]
+ }
+ ],
+ "laneId": 7,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 12,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915234,
+ 39.5950941
+ ],
+ [
+ -105.0915234,
+ 39.5950602
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -952,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ -377
+ ]
+ }
+ ],
+ "laneId": 12,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 13,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915804,
+ 39.5950941
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.5950596
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1440,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 7,
+ -390
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 13,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 10,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.09133,
+ 39.5944158
+ ],
+ [
+ -105.0913348,
+ 39.5939413
+ ],
+ [
+ -105.0913368,
+ 39.592921
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913356,
+ 39.592386
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 705,
+ -1919
+ ]
+ },
+ {
+ "delta": [
+ -1,
+ -7515
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -41,
+ -5272
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -17,
+ -11337
+ ]
+ },
+ {
+ "delta": [
+ 17,
+ -5938
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ -7
+ ]
+ }
+ ],
+ "laneId": 10,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 9,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912838,
+ 39.5946624
+ ],
+ [
+ -105.0912861,
+ 39.5940862
+ ],
+ [
+ -105.0912901,
+ 39.5933704
+ ],
+ [
+ -105.0912882,
+ 39.5923858
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1090,
+ -1930
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 9,
+ -4764
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -20,
+ -6402
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ -34,
+ -7953
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 16,
+ -10940
+ ],
+ "delevation": 20
+ }
+ ],
+ "laneId": 9,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 11,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.091375,
+ 39.5944888
+ ],
+ [
+ -105.0913568,
+ 39.5942534
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 350,
+ -1925
+ ]
+ },
+ {
+ "delta": [
+ -32,
+ -6698
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 156,
+ -2616
+ ]
+ }
+ ],
+ "laneId": 11,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 8,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0912421,
+ 39.5949129
+ ],
+ [
+ -105.0912427,
+ 39.5942475
+ ],
+ [
+ -105.0912568,
+ 39.5941003
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1557,
+ -1956
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -101,
+ -1956
+ ]
+ },
+ {
+ "delta": [
+ -5,
+ -7393
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -121,
+ -1636
+ ]
+ }
+ ],
+ "laneId": 8,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 15,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0927839,
+ 39.5951756
+ ],
+ [
+ -105.0941732,
+ 39.5951722
+ ],
+ [
+ -105.0952027,
+ 39.5951734
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2405,
+ -1018
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -9339,
+ 26
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11895,
+ -38
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -8814,
+ 13
+ ]
+ }
+ ],
+ "laneId": 15,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 16,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0931135,
+ 39.5952073
+ ],
+ [
+ -105.0944406,
+ 39.595204
+ ],
+ [
+ -105.0952041,
+ 39.5952041
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2337,
+ -656
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -12229,
+ 15
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -11362,
+ -37
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -6537,
+ 1
+ ]
+ }
+ ],
+ "laneId": 16,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 17,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0927239,
+ 39.5952377
+ ],
+ [
+ -105.0941207,
+ 39.5952375
+ ],
+ [
+ -105.0943034,
+ 39.5952213
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2338,
+ -284
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -8892,
+ -18
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11959,
+ -2
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -1564,
+ -180
+ ]
+ }
+ ],
+ "laneId": 17,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 14,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0940224,
+ 39.5951414
+ ],
+ [
+ -105.095203,
+ 39.5951408
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2401,
+ -1380
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -19947,
+ 8
+ ],
+ "delevation": 80
+ },
+ {
+ "delta": [
+ -10108,
+ -7
+ ]
+ }
+ ],
+ "laneId": 14,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 18,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916766,
+ 39.595308
+ ],
+ [
+ -105.0917443,
+ 39.5953067
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2264,
+ 479
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -580,
+ -14
+ ]
+ }
+ ],
+ "laneId": 18,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 19,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916758,
+ 39.5953365
+ ],
+ [
+ -105.0917363,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2257,
+ 796
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -518,
+ 0
+ ]
+ }
+ ],
+ "laneId": 19,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 20,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916734,
+ 39.5953755
+ ],
+ [
+ -105.0917299,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2236,
+ 1229
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -484,
+ 0
+ ]
+ }
+ ],
+ "laneId": 20,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 23,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0914927,
+ 39.5965421
+ ],
+ [
+ -105.091488,
+ 39.5974092
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914851,
+ 39.5981349
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -914,
+ 1903
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 225,
+ 12288
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 40,
+ 9634
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 32,
+ 8035
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ 28
+ ]
+ }
+ ],
+ "laneId": 23,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 22,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915441,
+ 39.59638
+ ],
+ [
+ -105.0915337,
+ 39.5974224
+ ],
+ [
+ -105.0915281,
+ 39.5981345
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1221,
+ 1914
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 92,
+ 10475
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 89,
+ 11582
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 48,
+ 7912
+ ],
+ "delevation": -30
+ }
+ ],
+ "laneId": 22,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 21,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916029,
+ 39.5957255
+ ],
+ [
+ -105.0916004,
+ 39.5962647
+ ],
+ [
+ -105.0915885,
+ 39.5966976
+ ],
+ [
+ -105.0915786,
+ 39.5977599
+ ],
+ [
+ -105.0915764,
+ 39.5981344
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1649,
+ 1935
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 16,
+ 3182
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 21,
+ 5991
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 102,
+ 4810
+ ]
+ },
+ {
+ "delta": [
+ 85,
+ 11803
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 19,
+ 4161
+ ],
+ "delevation": -20
+ }
+ ],
+ "laneId": 21,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 24,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0914714,
+ 39.5958506
+ ],
+ [
+ -105.0914611,
+ 39.596192
+ ],
+ [
+ -105.0914778,
+ 39.5963599
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -535,
+ 1926
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 28,
+ 4582
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 88,
+ 3793
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -143,
+ 1866
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 24,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 25,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0914355,
+ 39.5958506
+ ],
+ [
+ -105.0914461,
+ 39.596052
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -213,
+ 1913
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 14,
+ 4594
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -91,
+ 2238
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 25,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 26,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913276,
+ 39.5954361
+ ],
+ [
+ -105.0913284,
+ 39.5954678
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 724,
+ 1902
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 352
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 26,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 27,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912831,
+ 39.5954348
+ ],
+ [
+ -105.0912839,
+ 39.5954647
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1105,
+ 1888
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 332
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 27,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 28,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912264,
+ 39.5954336
+ ],
+ [
+ -105.091228,
+ 39.5954647
+ ],
+ [
+ -105.091228,
+ 39.5954653
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1591,
+ 1874
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -14,
+ 346
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 28,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ }
+ ]
+ },
+ "connectingLanesFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": "2-19",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0916758,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 2,
+ "egressLaneId": 19
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "3-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 3,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "1-28",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0912264,
+ 39.5954336
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 1,
+ "egressLaneId": 28
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "4-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 7,
+ "ingressLaneId": 4,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "10-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 10,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "9-27",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912831,
+ 39.5954348
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 9,
+ "egressLaneId": 27
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "11-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 1,
+ "ingressLaneId": 11,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "8-7",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0911443,
+ 39.5951332
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 8,
+ "egressLaneId": 7
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "15-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 15,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "16-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 16,
+ "egressLaneId": 5
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "17-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 3,
+ "ingressLaneId": 17,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "14-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 14,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "23-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 23,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "22-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 22,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "21-20",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916734,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 21,
+ "egressLaneId": 20
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "24-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 24,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "25-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 25,
+ "egressLaneId": 5
+ }
+ }
+ ]
+ },
+ "properties": {
+ "schemaVersion": 1,
+ "messageType": "MAP",
+ "odeReceivedAt": "2025-01-31T23:36:23.542Z",
+ "originIp": "172.20.0.1",
+ "intersectionId": 13110,
+ "msgIssueRevision": 0,
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677
+ },
+ "cti4501Conformant": false,
+ "validationMessages": [
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].id.region: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].id",
+ "schemaPath": "#/$defs/J2735IntersectionReferenceID/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].speedLimits: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0]",
+ "schemaPath": "#/$defs/J2735IntersectionGeometry/required"
+ }
+ ],
+ "laneWidth": 366,
+ "mapSource": "RSU",
+ "timeStamp": "2025-01-31T23:36:23.542Z"
+ }
+ }
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference-1-hour-later.json b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference-1-hour-later.json
new file mode 100644
index 0000000..af91ff7
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference-1-hour-later.json
@@ -0,0 +1,3443 @@
+{
+ "mapFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 2,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0899239,
+ 39.5953231
+ ],
+ [
+ -105.0896005,
+ 39.5953332
+ ],
+ [
+ -105.0888831,
+ 39.595317
+ ],
+ [
+ -105.088108,
+ 39.5953159
+ ],
+ [
+ -105.0876637,
+ 39.5953153
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2225,
+ 808
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 10517,
+ -161
+ ],
+ "delevation": -60
+ },
+ {
+ "delta": [
+ 2769,
+ 112
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6142,
+ -180
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 6636,
+ -12
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 3804,
+ -7
+ ]
+ }
+ ],
+ "laneId": 2,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 3,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0908101,
+ 39.5953039
+ ],
+ [
+ -105.0900791,
+ 39.5952962
+ ],
+ [
+ -105.0896801,
+ 39.5952874
+ ],
+ [
+ -105.0888781,
+ 39.5952839
+ ],
+ [
+ -105.0885678,
+ 39.5952789
+ ],
+ [
+ -105.0880704,
+ 39.5952849
+ ],
+ [
+ -105.0876638,
+ 39.5952849
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2222,
+ 515
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 2933,
+ -82
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6259,
+ -85
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 3416,
+ -98
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 6867,
+ -39
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 2657,
+ -55
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 4259,
+ 67
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 3481,
+ 0
+ ]
+ }
+ ],
+ "laneId": 3,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 1,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0899328,
+ 39.5953544
+ ],
+ [
+ -105.0897165,
+ 39.5953447
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2215,
+ 1218
+ ]
+ },
+ {
+ "delta": [
+ 10451,
+ -223
+ ],
+ "delevation": -70
+ },
+ {
+ "delta": [
+ 1852,
+ -108
+ ],
+ "delevation": -10
+ }
+ ],
+ "laneId": 1,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 4,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0903143,
+ 39.5952555
+ ],
+ [
+ -105.0902511,
+ 39.5952591
+ ],
+ [
+ -105.0900995,
+ 39.5952797
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2213,
+ -124
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 7187,
+ 20
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 541,
+ 40
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 1298,
+ 229
+ ]
+ }
+ ],
+ "laneId": 4,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 6,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5951732
+ ],
+ [
+ -105.0911048,
+ 39.5951738
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -1019
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 7
+ ]
+ }
+ ],
+ "laneId": 6,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 5,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5952053
+ ],
+ [
+ -105.0911079,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -662
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 338,
+ 0
+ ]
+ }
+ ],
+ "laneId": 5,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 7,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911443,
+ 39.5951332
+ ],
+ [
+ -105.0911017,
+ 39.5951356
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2294,
+ -1463
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 27
+ ]
+ }
+ ],
+ "laneId": 7,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 12,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915234,
+ 39.5950941
+ ],
+ [
+ -105.0915234,
+ 39.5950602
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -952,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ -377
+ ]
+ }
+ ],
+ "laneId": 12,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 13,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915804,
+ 39.5950941
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.5950596
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1440,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 7,
+ -390
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 13,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 10,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.09133,
+ 39.5944158
+ ],
+ [
+ -105.0913348,
+ 39.5939413
+ ],
+ [
+ -105.0913368,
+ 39.592921
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913356,
+ 39.592386
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 705,
+ -1919
+ ]
+ },
+ {
+ "delta": [
+ -1,
+ -7515
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -41,
+ -5272
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -17,
+ -11337
+ ]
+ },
+ {
+ "delta": [
+ 17,
+ -5938
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ -7
+ ]
+ }
+ ],
+ "laneId": 10,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 9,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912838,
+ 39.5946624
+ ],
+ [
+ -105.0912861,
+ 39.5940862
+ ],
+ [
+ -105.0912901,
+ 39.5933704
+ ],
+ [
+ -105.0912882,
+ 39.5923858
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1090,
+ -1930
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 9,
+ -4764
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -20,
+ -6402
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ -34,
+ -7953
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 16,
+ -10940
+ ],
+ "delevation": 20
+ }
+ ],
+ "laneId": 9,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 11,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.091375,
+ 39.5944888
+ ],
+ [
+ -105.0913568,
+ 39.5942534
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 350,
+ -1925
+ ]
+ },
+ {
+ "delta": [
+ -32,
+ -6698
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 156,
+ -2616
+ ]
+ }
+ ],
+ "laneId": 11,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 8,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0912421,
+ 39.5949129
+ ],
+ [
+ -105.0912427,
+ 39.5942475
+ ],
+ [
+ -105.0912568,
+ 39.5941003
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1557,
+ -1956
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -101,
+ -1956
+ ]
+ },
+ {
+ "delta": [
+ -5,
+ -7393
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -121,
+ -1636
+ ]
+ }
+ ],
+ "laneId": 8,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 15,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0927839,
+ 39.5951756
+ ],
+ [
+ -105.0941732,
+ 39.5951722
+ ],
+ [
+ -105.0952027,
+ 39.5951734
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2405,
+ -1018
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -9339,
+ 26
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11895,
+ -38
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -8814,
+ 13
+ ]
+ }
+ ],
+ "laneId": 15,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 16,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0931135,
+ 39.5952073
+ ],
+ [
+ -105.0944406,
+ 39.595204
+ ],
+ [
+ -105.0952041,
+ 39.5952041
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2337,
+ -656
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -12229,
+ 15
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -11362,
+ -37
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -6537,
+ 1
+ ]
+ }
+ ],
+ "laneId": 16,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 17,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0927239,
+ 39.5952377
+ ],
+ [
+ -105.0941207,
+ 39.5952375
+ ],
+ [
+ -105.0943034,
+ 39.5952213
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2338,
+ -284
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -8892,
+ -18
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11959,
+ -2
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -1564,
+ -180
+ ]
+ }
+ ],
+ "laneId": 17,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 14,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0940224,
+ 39.5951414
+ ],
+ [
+ -105.095203,
+ 39.5951408
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2401,
+ -1380
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -19947,
+ 8
+ ],
+ "delevation": 80
+ },
+ {
+ "delta": [
+ -10108,
+ -7
+ ]
+ }
+ ],
+ "laneId": 14,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 18,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916766,
+ 39.595308
+ ],
+ [
+ -105.0917443,
+ 39.5953067
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2264,
+ 479
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -580,
+ -14
+ ]
+ }
+ ],
+ "laneId": 18,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 19,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916758,
+ 39.5953365
+ ],
+ [
+ -105.0917363,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2257,
+ 796
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -518,
+ 0
+ ]
+ }
+ ],
+ "laneId": 19,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 20,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916734,
+ 39.5953755
+ ],
+ [
+ -105.0917299,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2236,
+ 1229
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -484,
+ 0
+ ]
+ }
+ ],
+ "laneId": 20,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 23,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0914927,
+ 39.5965421
+ ],
+ [
+ -105.091488,
+ 39.5974092
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914851,
+ 39.5981349
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -914,
+ 1903
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 225,
+ 12288
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 40,
+ 9634
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 32,
+ 8035
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ 28
+ ]
+ }
+ ],
+ "laneId": 23,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 22,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915441,
+ 39.59638
+ ],
+ [
+ -105.0915337,
+ 39.5974224
+ ],
+ [
+ -105.0915281,
+ 39.5981345
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1221,
+ 1914
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 92,
+ 10475
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 89,
+ 11582
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 48,
+ 7912
+ ],
+ "delevation": -30
+ }
+ ],
+ "laneId": 22,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 21,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916029,
+ 39.5957255
+ ],
+ [
+ -105.0916004,
+ 39.5962647
+ ],
+ [
+ -105.0915885,
+ 39.5966976
+ ],
+ [
+ -105.0915786,
+ 39.5977599
+ ],
+ [
+ -105.0915764,
+ 39.5981344
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1649,
+ 1935
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 16,
+ 3182
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 21,
+ 5991
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 102,
+ 4810
+ ]
+ },
+ {
+ "delta": [
+ 85,
+ 11803
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 19,
+ 4161
+ ],
+ "delevation": -20
+ }
+ ],
+ "laneId": 21,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 24,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0914714,
+ 39.5958506
+ ],
+ [
+ -105.0914611,
+ 39.596192
+ ],
+ [
+ -105.0914778,
+ 39.5963599
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -535,
+ 1926
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 28,
+ 4582
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 88,
+ 3793
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -143,
+ 1866
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 24,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 25,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0914355,
+ 39.5958506
+ ],
+ [
+ -105.0914461,
+ 39.596052
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -213,
+ 1913
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 14,
+ 4594
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -91,
+ 2238
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 25,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 26,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913276,
+ 39.5954361
+ ],
+ [
+ -105.0913284,
+ 39.5954678
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 724,
+ 1902
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 352
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 26,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 27,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912831,
+ 39.5954348
+ ],
+ [
+ -105.0912839,
+ 39.5954647
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1105,
+ 1888
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 332
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 27,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 28,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912264,
+ 39.5954336
+ ],
+ [
+ -105.091228,
+ 39.5954647
+ ],
+ [
+ -105.091228,
+ 39.5954653
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1591,
+ 1874
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -14,
+ 346
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 28,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ }
+ ]
+ },
+ "connectingLanesFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": "2-19",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0916758,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 2,
+ "egressLaneId": 19
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "3-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 3,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "1-28",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0912264,
+ 39.5954336
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 1,
+ "egressLaneId": 28
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "4-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 7,
+ "ingressLaneId": 4,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "10-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 10,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "9-27",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912831,
+ 39.5954348
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 9,
+ "egressLaneId": 27
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "11-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 1,
+ "ingressLaneId": 11,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "8-7",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0911443,
+ 39.5951332
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 8,
+ "egressLaneId": 7
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "15-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 15,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "16-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 16,
+ "egressLaneId": 5
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "17-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 3,
+ "ingressLaneId": 17,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "14-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 14,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "23-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 23,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "22-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 22,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "21-20",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916734,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 21,
+ "egressLaneId": 20
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "24-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 24,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "25-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 25,
+ "egressLaneId": 5
+ }
+ }
+ ]
+ },
+ "properties": {
+ "schemaVersion": 1,
+ "messageType": "MAP",
+ "odeReceivedAt": "2025-02-01T00:36:23.542Z",
+ "originIp": "172.20.0.1",
+ "intersectionId": 12110,
+ "msgIssueRevision": 0,
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677
+ },
+ "cti4501Conformant": false,
+ "validationMessages": [
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].id.region: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].id",
+ "schemaPath": "#/$defs/J2735IntersectionReferenceID/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].speedLimits: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0]",
+ "schemaPath": "#/$defs/J2735IntersectionGeometry/required"
+ }
+ ],
+ "laneWidth": 366,
+ "mapSource": "RSU",
+ "timeStamp": "2025-02-01T00:36:23.542Z"
+ }
+ }
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference.json b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference.json
new file mode 100644
index 0000000..fdf4a97
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map/sample.processed_map-reference.json
@@ -0,0 +1,3443 @@
+{
+ "mapFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 2,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0899239,
+ 39.5953231
+ ],
+ [
+ -105.0896005,
+ 39.5953332
+ ],
+ [
+ -105.0888831,
+ 39.595317
+ ],
+ [
+ -105.088108,
+ 39.5953159
+ ],
+ [
+ -105.0876637,
+ 39.5953153
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2225,
+ 808
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 10517,
+ -161
+ ],
+ "delevation": -60
+ },
+ {
+ "delta": [
+ 2769,
+ 112
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6142,
+ -180
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 6636,
+ -12
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 3804,
+ -7
+ ]
+ }
+ ],
+ "laneId": 2,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 3,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0908101,
+ 39.5953039
+ ],
+ [
+ -105.0900791,
+ 39.5952962
+ ],
+ [
+ -105.0896801,
+ 39.5952874
+ ],
+ [
+ -105.0888781,
+ 39.5952839
+ ],
+ [
+ -105.0885678,
+ 39.5952789
+ ],
+ [
+ -105.0880704,
+ 39.5952849
+ ],
+ [
+ -105.0876638,
+ 39.5952849
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2222,
+ 515
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 2933,
+ -82
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 6259,
+ -85
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 3416,
+ -98
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 6867,
+ -39
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 2657,
+ -55
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 4259,
+ 67
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 3481,
+ 0
+ ]
+ }
+ ],
+ "laneId": 3,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 1,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0899328,
+ 39.5953544
+ ],
+ [
+ -105.0897165,
+ 39.5953447
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2215,
+ 1218
+ ]
+ },
+ {
+ "delta": [
+ 10451,
+ -223
+ ],
+ "delevation": -70
+ },
+ {
+ "delta": [
+ 1852,
+ -108
+ ],
+ "delevation": -10
+ }
+ ],
+ "laneId": 1,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 4,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0903143,
+ 39.5952555
+ ],
+ [
+ -105.0902511,
+ 39.5952591
+ ],
+ [
+ -105.0900995,
+ 39.5952797
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2213,
+ -124
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 7187,
+ 20
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ 541,
+ 40
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 1298,
+ 229
+ ]
+ }
+ ],
+ "laneId": 4,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 6,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5951732
+ ],
+ [
+ -105.0911048,
+ 39.5951738
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -1019
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 7
+ ]
+ }
+ ],
+ "laneId": 6,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 5,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911474,
+ 39.5952053
+ ],
+ [
+ -105.0911079,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2267,
+ -662
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 338,
+ 0
+ ]
+ }
+ ],
+ "laneId": 5,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 7,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911443,
+ 39.5951332
+ ],
+ [
+ -105.0911017,
+ 39.5951356
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 2294,
+ -1463
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 365,
+ 27
+ ]
+ }
+ ],
+ "laneId": 7,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 12,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915234,
+ 39.5950941
+ ],
+ [
+ -105.0915234,
+ 39.5950602
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -952,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ -377
+ ]
+ }
+ ],
+ "laneId": 12,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 13,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915804,
+ 39.5950941
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.595059
+ ],
+ [
+ -105.0915796,
+ 39.5950596
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1440,
+ -1898
+ ]
+ },
+ {
+ "delta": [
+ 7,
+ -390
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 13,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 10,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.09133,
+ 39.5944158
+ ],
+ [
+ -105.0913348,
+ 39.5939413
+ ],
+ [
+ -105.0913368,
+ 39.592921
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913348,
+ 39.5923866
+ ],
+ [
+ -105.0913356,
+ 39.592386
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 705,
+ -1919
+ ]
+ },
+ {
+ "delta": [
+ -1,
+ -7515
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -41,
+ -5272
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -17,
+ -11337
+ ]
+ },
+ {
+ "delta": [
+ 17,
+ -5938
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ -7
+ ]
+ }
+ ],
+ "laneId": 10,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 9,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912838,
+ 39.5946624
+ ],
+ [
+ -105.0912861,
+ 39.5940862
+ ],
+ [
+ -105.0912901,
+ 39.5933704
+ ],
+ [
+ -105.0912882,
+ 39.5923858
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1090,
+ -1930
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 9,
+ -4764
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -20,
+ -6402
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ -34,
+ -7953
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ 16,
+ -10940
+ ],
+ "delevation": 20
+ }
+ ],
+ "laneId": 9,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 11,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.091375,
+ 39.5944888
+ ],
+ [
+ -105.0913568,
+ 39.5942534
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 350,
+ -1925
+ ]
+ },
+ {
+ "delta": [
+ -32,
+ -6698
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 156,
+ -2616
+ ]
+ }
+ ],
+ "laneId": 11,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 8,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0912421,
+ 39.5949129
+ ],
+ [
+ -105.0912427,
+ 39.5942475
+ ],
+ [
+ -105.0912568,
+ 39.5941003
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1557,
+ -1956
+ ],
+ "delevation": -10
+ },
+ {
+ "delta": [
+ -101,
+ -1956
+ ]
+ },
+ {
+ "delta": [
+ -5,
+ -7393
+ ],
+ "delevation": -40
+ },
+ {
+ "delta": [
+ -121,
+ -1636
+ ]
+ }
+ ],
+ "laneId": 8,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 15,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0927839,
+ 39.5951756
+ ],
+ [
+ -105.0941732,
+ 39.5951722
+ ],
+ [
+ -105.0952027,
+ 39.5951734
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2405,
+ -1018
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -9339,
+ 26
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11895,
+ -38
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -8814,
+ 13
+ ]
+ }
+ ],
+ "laneId": 15,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 16,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0931135,
+ 39.5952073
+ ],
+ [
+ -105.0944406,
+ 39.595204
+ ],
+ [
+ -105.0952041,
+ 39.5952041
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2337,
+ -656
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -12229,
+ 15
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -11362,
+ -37
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -6537,
+ 1
+ ]
+ }
+ ],
+ "laneId": 16,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 17,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0927239,
+ 39.5952377
+ ],
+ [
+ -105.0941207,
+ 39.5952375
+ ],
+ [
+ -105.0943034,
+ 39.5952213
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2338,
+ -284
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -8892,
+ -18
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ -11959,
+ -2
+ ],
+ "delevation": 50
+ },
+ {
+ "delta": [
+ -1564,
+ -180
+ ]
+ }
+ ],
+ "laneId": 17,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 14,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0940224,
+ 39.5951414
+ ],
+ [
+ -105.095203,
+ 39.5951408
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2401,
+ -1380
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -19947,
+ 8
+ ],
+ "delevation": 80
+ },
+ {
+ "delta": [
+ -10108,
+ -7
+ ]
+ }
+ ],
+ "laneId": 14,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 18,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916766,
+ 39.595308
+ ],
+ [
+ -105.0917443,
+ 39.5953067
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2264,
+ 479
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -580,
+ -14
+ ]
+ }
+ ],
+ "laneId": 18,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 19,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916758,
+ 39.5953365
+ ],
+ [
+ -105.0917363,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2257,
+ 796
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -518,
+ 0
+ ]
+ }
+ ],
+ "laneId": 19,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 20,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916734,
+ 39.5953755
+ ],
+ [
+ -105.0917299,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -2236,
+ 1229
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ -484,
+ 0
+ ]
+ }
+ ],
+ "laneId": 20,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 23,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0914927,
+ 39.5965421
+ ],
+ [
+ -105.091488,
+ 39.5974092
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914843,
+ 39.5981324
+ ],
+ [
+ -105.0914851,
+ 39.5981349
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -914,
+ 1903
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 225,
+ 12288
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 40,
+ 9634
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 32,
+ 8035
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 0,
+ 0
+ ]
+ },
+ {
+ "delta": [
+ -7,
+ 28
+ ]
+ }
+ ],
+ "laneId": 23,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 22,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915441,
+ 39.59638
+ ],
+ [
+ -105.0915337,
+ 39.5974224
+ ],
+ [
+ -105.0915281,
+ 39.5981345
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1221,
+ 1914
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 92,
+ 10475
+ ],
+ "delevation": 30
+ },
+ {
+ "delta": [
+ 89,
+ 11582
+ ],
+ "delevation": -20
+ },
+ {
+ "delta": [
+ 48,
+ 7912
+ ],
+ "delevation": -30
+ }
+ ],
+ "laneId": 22,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 21,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916029,
+ 39.5957255
+ ],
+ [
+ -105.0916004,
+ 39.5962647
+ ],
+ [
+ -105.0915885,
+ 39.5966976
+ ],
+ [
+ -105.0915786,
+ 39.5977599
+ ],
+ [
+ -105.0915764,
+ 39.5981344
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -1649,
+ 1935
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 16,
+ 3182
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 21,
+ 5991
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 102,
+ 4810
+ ]
+ },
+ {
+ "delta": [
+ 85,
+ 11803
+ ],
+ "delevation": -30
+ },
+ {
+ "delta": [
+ 19,
+ 4161
+ ],
+ "delevation": -20
+ }
+ ],
+ "laneId": 21,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 24,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0914714,
+ 39.5958506
+ ],
+ [
+ -105.0914611,
+ 39.596192
+ ],
+ [
+ -105.0914778,
+ 39.5963599
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -535,
+ 1926
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 28,
+ 4582
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ 88,
+ 3793
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -143,
+ 1866
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 24,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 25,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0914355,
+ 39.5958506
+ ],
+ [
+ -105.0914461,
+ 39.596052
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ -213,
+ 1913
+ ],
+ "delevation": 20
+ },
+ {
+ "delta": [
+ 14,
+ 4594
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -91,
+ 2238
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 25,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 26,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913276,
+ 39.5954361
+ ],
+ [
+ -105.0913284,
+ 39.5954678
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 724,
+ 1902
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 352
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 26,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 27,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912831,
+ 39.5954348
+ ],
+ [
+ -105.0912839,
+ 39.5954647
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1105,
+ 1888
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -7,
+ 332
+ ],
+ "delevation": 10
+ }
+ ],
+ "laneId": 27,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 28,
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912264,
+ 39.5954336
+ ],
+ [
+ -105.091228,
+ 39.5954647
+ ],
+ [
+ -105.091228,
+ 39.5954653
+ ]
+ ]
+ },
+ "properties": {
+ "nodes": [
+ {
+ "delta": [
+ 1591,
+ 1874
+ ],
+ "delevation": 10
+ },
+ {
+ "delta": [
+ -14,
+ 346
+ ]
+ },
+ {
+ "delta": [
+ 0,
+ 7
+ ]
+ }
+ ],
+ "laneId": 28,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ }
+ ]
+ },
+ "connectingLanesFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": "2-19",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911523,
+ 39.5953376
+ ],
+ [
+ -105.0916758,
+ 39.5953365
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 2,
+ "egressLaneId": 19
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "3-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911527,
+ 39.5953113
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 3,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "1-28",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911535,
+ 39.5953745
+ ],
+ [
+ -105.0912264,
+ 39.5954336
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 1,
+ "egressLaneId": 28
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "4-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0911537,
+ 39.5952537
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 7,
+ "ingressLaneId": 4,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "10-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913299,
+ 39.5950922
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 10,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "9-27",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912849,
+ 39.5950912
+ ],
+ [
+ -105.0912831,
+ 39.5954348
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 9,
+ "egressLaneId": 27
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "11-18",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0913713,
+ 39.5950916
+ ],
+ [
+ -105.0916766,
+ 39.595308
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 1,
+ "ingressLaneId": 11,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "8-7",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0912303,
+ 39.5950889
+ ],
+ [
+ -105.0911443,
+ 39.5951332
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 8,
+ "egressLaneId": 7
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "15-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916931,
+ 39.5951733
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 15,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "16-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916852,
+ 39.5952059
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 16,
+ "egressLaneId": 5
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "17-26",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916853,
+ 39.5952393
+ ],
+ [
+ -105.0913276,
+ 39.5954361
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 3,
+ "ingressLaneId": 17,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "14-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916926,
+ 39.5951407
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 14,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "23-12",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.091519,
+ 39.5954362
+ ],
+ [
+ -105.0915234,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 23,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "22-13",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0915548,
+ 39.5954372
+ ],
+ [
+ -105.0915804,
+ 39.5950941
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 22,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "21-20",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0916048,
+ 39.5954391
+ ],
+ [
+ -105.0916734,
+ 39.5953755
+ ]
+ ]
+ },
+ "properties": {
+ "ingressLaneId": 21,
+ "egressLaneId": 20
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "24-6",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914747,
+ 39.5954382
+ ],
+ [
+ -105.0911474,
+ 39.5951732
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 24,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "25-5",
+ "geometry": {
+ "type": "LineString",
+ "coordinates": [
+ [
+ -105.0914371,
+ 39.5954371
+ ],
+ [
+ -105.0911474,
+ 39.5952053
+ ]
+ ]
+ },
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 25,
+ "egressLaneId": 5
+ }
+ }
+ ]
+ },
+ "properties": {
+ "schemaVersion": 1,
+ "messageType": "MAP",
+ "odeReceivedAt": "2025-01-31T23:36:23.542Z",
+ "originIp": "172.20.0.1",
+ "intersectionId": 12110,
+ "msgIssueRevision": 0,
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677
+ },
+ "cti4501Conformant": false,
+ "validationMessages": [
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].id.region: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].id",
+ "schemaPath": "#/$defs/J2735IntersectionReferenceID/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[2].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[4]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[5]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[6]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[7]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[8]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[12].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[16].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[17]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[18]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[19]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0].signalGroup: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[22].connectsTo.connectsTo[0]",
+ "schemaPath": "#/$defs/J2735Connection/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[25]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[26]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].maneuvers: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27].connectsTo: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0].laneSet.GenericLane[27]",
+ "schemaPath": "#/$defs/J2735GenericLane/required"
+ },
+ {
+ "message": "$.payload.data.intersections.intersectionGeometry[0].speedLimits: is missing but it is required",
+ "jsonPath": "$.payload.data.intersections.intersectionGeometry[0]",
+ "schemaPath": "#/$defs/J2735IntersectionGeometry/required"
+ }
+ ],
+ "laneWidth": 366,
+ "mapSource": "RSU",
+ "timeStamp": "2025-01-31T23:36:23.542Z"
+ }
+ }
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-different.json b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-different.json
new file mode 100644
index 0000000..b8616d4
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-different.json
@@ -0,0 +1,1829 @@
+{
+ "mapFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 2,
+ "geometry": "LINESTRING (-105.0911523 39.5953376, -105.0899239 39.5953231, -105.0896005 39.5953332, -105.0888831 39.595317, -105.088108 39.5953159, -105.0876637 39.5953153)",
+ "properties": {
+ "laneId": 2,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 3,
+ "geometry": "LINESTRING (-105.0911527 39.5953113, -105.0908101 39.5953039, -105.0900791 39.5952962, -105.0896801 39.5952874, -105.0888781 39.5952839, -105.0885678 39.5952789, -105.0880704 39.5952849, -105.0876638 39.5952849)",
+ "properties": {
+ "laneId": 3,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 1,
+ "geometry": "LINESTRING (-105.0911535 39.5953745, -105.0899328 39.5953544, -105.0897165 39.5953447)",
+ "properties": {
+ "laneId": 1,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 4,
+ "geometry": "LINESTRING (-105.0911537 39.5952537, -105.0903143 39.5952555, -105.0902511 39.5952591, -105.0900995 39.5952797)",
+ "properties": {
+ "laneId": 4,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 6,
+ "geometry": "LINESTRING (-105.0911474 39.5951732, -105.0911048 39.5951738)",
+ "properties": {
+ "laneId": 6,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 5,
+ "geometry": "LINESTRING (-105.0911474 39.5952053, -105.0911079 39.5952053)",
+ "properties": {
+ "laneId": 5,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 7,
+ "geometry": "LINESTRING (-105.0911443 39.5951332, -105.0911017 39.5951356)",
+ "properties": {
+ "laneId": 7,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 12,
+ "geometry": "LINESTRING (-105.0915234 39.5950941, -105.0915234 39.5950602)",
+ "properties": {
+ "laneId": 12,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 13,
+ "geometry": "LINESTRING (-105.0915804 39.5950941, -105.0915796 39.595059, -105.0915796 39.595059, -105.0915796 39.5950596)",
+ "properties": {
+ "laneId": 13,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 10,
+ "geometry": "LINESTRING (-105.0913299 39.5950922, -105.09133 39.5944158, -105.0913348 39.5939413, -105.0913368 39.592921, -105.0913348 39.5923866, -105.0913348 39.5923866, -105.0913356 39.592386)",
+ "properties": {
+ "laneId": 10,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 9,
+ "geometry": "LINESTRING (-105.0912849 39.5950912, -105.0912838 39.5946624, -105.0912861 39.5940862, -105.0912901 39.5933704, -105.0912882 39.5923858)",
+ "properties": {
+ "laneId": 9,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 11,
+ "geometry": "LINESTRING (-105.0913713 39.5950916, -105.091375 39.5944888, -105.0913568 39.5942534)",
+ "properties": {
+ "laneId": 11,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 8,
+ "geometry": "LINESTRING (-105.0912303 39.5950889, -105.0912421 39.5949129, -105.0912427 39.5942475, -105.0912568 39.5941003)",
+ "properties": {
+ "laneId": 8,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 15,
+ "geometry": "LINESTRING (-105.0916931 39.5951733, -105.0927839 39.5951756, -105.0941732 39.5951722, -105.0952027 39.5951734)",
+ "properties": {
+ "laneId": 15,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 16,
+ "geometry": "LINESTRING (-105.0916852 39.5952059, -105.0931135 39.5952073, -105.0944406 39.595204, -105.0952041 39.5952041)",
+ "properties": {
+ "laneId": 16,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 17,
+ "geometry": "LINESTRING (-105.0916853 39.5952393, -105.0927239 39.5952377, -105.0941207 39.5952375, -105.0943034 39.5952213)",
+ "properties": {
+ "laneId": 17,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 14,
+ "geometry": "LINESTRING (-105.0916926 39.5951407, -105.0940224 39.5951414, -105.095203 39.5951408)",
+ "properties": {
+ "laneId": 14,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 18,
+ "geometry": "LINESTRING (-105.0916766 39.595308, -105.0917443 39.5953067)",
+ "properties": {
+ "laneId": 18,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 19,
+ "geometry": "LINESTRING (-105.0916758 39.5953365, -105.0917363 39.5953365)",
+ "properties": {
+ "laneId": 19,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 20,
+ "geometry": "LINESTRING (-105.0916734 39.5953755, -105.0917299 39.5953755)",
+ "properties": {
+ "laneId": 20,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 23,
+ "geometry": "LINESTRING (-105.091519 39.5954362, -105.0914927 39.5965421, -105.091488 39.5974092, -105.0914843 39.5981324, -105.0914843 39.5981324, -105.0914851 39.5981349)",
+ "properties": {
+ "laneId": 23,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 22,
+ "geometry": "LINESTRING (-105.0915548 39.5954372, -105.0915441 39.59638, -105.0915337 39.5974224, -105.0915281 39.5981345)",
+ "properties": {
+ "laneId": 22,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 21,
+ "geometry": "LINESTRING (-105.0916048 39.5954391, -105.0916029 39.5957255, -105.0916004 39.5962647, -105.0915885 39.5966976, -105.0915786 39.5977599, -105.0915764 39.5981344)",
+ "properties": {
+ "laneId": 21,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 24,
+ "geometry": "LINESTRING (-105.0914747 39.5954382, -105.0914714 39.5958506, -105.0914611 39.596192, -105.0914778 39.5963599)",
+ "properties": {
+ "laneId": 24,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 25,
+ "geometry": "LINESTRING (-105.0914371 39.5954371, -105.0914355 39.5958506, -105.0914461 39.596052)",
+ "properties": {
+ "laneId": 25,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 26,
+ "geometry": "LINESTRING (-105.0913276 39.5954361, -105.0913284 39.5954678)",
+ "properties": {
+ "laneId": 26,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 27,
+ "geometry": "LINESTRING (-105.0912831 39.5954348, -105.0912839 39.5954647)",
+ "properties": {
+ "laneId": 27,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 28,
+ "geometry": "LINESTRING (-105.0912264 39.5954336, -105.091228 39.5954647, -105.091228 39.5954653)",
+ "properties": {
+ "laneId": 28,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ }
+ ]
+ },
+ "connectingLanesFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": "2-19",
+ "geometry": "LINESTRING (-105.0911523 39.5953376, -105.0916758 39.5953365)",
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 2,
+ "egressLaneId": 19
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "3-18",
+ "geometry": "LINESTRING (-105.0911527 39.5953113, -105.0916766 39.595308)",
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 3,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "1-28",
+ "geometry": "LINESTRING (-105.0911535 39.5953745, -105.0912264 39.5954336)",
+ "properties": {
+ "ingressLaneId": 1,
+ "egressLaneId": 28
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "4-12",
+ "geometry": "LINESTRING (-105.0911537 39.5952537, -105.0915234 39.5950941)",
+ "properties": {
+ "signalGroupId": 7,
+ "ingressLaneId": 4,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "10-26",
+ "geometry": "LINESTRING (-105.0913299 39.5950922, -105.0913276 39.5954361)",
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 10,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "9-27",
+ "geometry": "LINESTRING (-105.0912849 39.5950912, -105.0912831 39.5954348)",
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 9,
+ "egressLaneId": 27
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "11-18",
+ "geometry": "LINESTRING (-105.0913713 39.5950916, -105.0916766 39.595308)",
+ "properties": {
+ "signalGroupId": 1,
+ "ingressLaneId": 11,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "8-7",
+ "geometry": "LINESTRING (-105.0912303 39.5950889, -105.0911443 39.5951332)",
+ "properties": {
+ "ingressLaneId": 8,
+ "egressLaneId": 7
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "15-6",
+ "geometry": "LINESTRING (-105.0916931 39.5951733, -105.0911474 39.5951732)",
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 15,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "16-5",
+ "geometry": "LINESTRING (-105.0916852 39.5952059, -105.0911474 39.5952053)",
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 16,
+ "egressLaneId": 5
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "17-26",
+ "geometry": "LINESTRING (-105.0916853 39.5952393, -105.0913276 39.5954361)",
+ "properties": {
+ "signalGroupId": 3,
+ "ingressLaneId": 17,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "14-13",
+ "geometry": "LINESTRING (-105.0916926 39.5951407, -105.0915804 39.5950941)",
+ "properties": {
+ "ingressLaneId": 14,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "23-12",
+ "geometry": "LINESTRING (-105.091519 39.5954362, -105.0915234 39.5950941)",
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 23,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "22-13",
+ "geometry": "LINESTRING (-105.0915548 39.5954372, -105.0915804 39.5950941)",
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 22,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "21-20",
+ "geometry": "LINESTRING (-105.0916048 39.5954391, -105.0916734 39.5953755)",
+ "properties": {
+ "ingressLaneId": 21,
+ "egressLaneId": 20
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "24-6",
+ "geometry": "LINESTRING (-105.0914747 39.5954382, -105.0911474 39.5951732)",
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 24,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "25-5",
+ "geometry": "LINESTRING (-105.0914371 39.5954371, -105.0911474 39.5952053)",
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 25,
+ "egressLaneId": 5
+ }
+ }
+ ]
+ },
+ "properties": {
+ "schemaVersion": 1,
+ "messageType": "MAP",
+ "odeReceivedAt": "2025-01-31T23:50:49.19Z",
+ "originIp": "172.20.0.1",
+ "intersectionId": 13110,
+ "msgIssueRevision": 0,
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677
+ },
+ "cti4501Conformant": false,
+ "laneWidth": 366,
+ "mapSource": "RSU",
+ "timeStamp": "2025-01-31T23:50:49.19Z"
+ }
+ }
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference-1-hour-later.json b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference-1-hour-later.json
new file mode 100644
index 0000000..90dad7d
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference-1-hour-later.json
@@ -0,0 +1,1829 @@
+{
+ "mapFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": 2,
+ "geometry": "LINESTRING (-105.0911523 39.5953376, -105.0899239 39.5953231, -105.0896005 39.5953332, -105.0888831 39.595317, -105.088108 39.5953159, -105.0876637 39.5953153)",
+ "properties": {
+ "laneId": 2,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 19,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 3,
+ "geometry": "LINESTRING (-105.0911527 39.5953113, -105.0908101 39.5953039, -105.0900791 39.5952962, -105.0896801 39.5952874, -105.0888781 39.5952839, -105.0885678 39.5952789, -105.0880704 39.5952849, -105.0876638 39.5952849)",
+ "properties": {
+ "laneId": 3,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 4,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 1,
+ "geometry": "LINESTRING (-105.0911535 39.5953745, -105.0899328 39.5953544, -105.0897165 39.5953447)",
+ "properties": {
+ "laneId": 1,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 28,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 4,
+ "geometry": "LINESTRING (-105.0911537 39.5952537, -105.0903143 39.5952555, -105.0902511 39.5952591, -105.0900995 39.5952797)",
+ "properties": {
+ "laneId": 4,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 1,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 7,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 6,
+ "geometry": "LINESTRING (-105.0911474 39.5951732, -105.0911048 39.5951738)",
+ "properties": {
+ "laneId": 6,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 5,
+ "geometry": "LINESTRING (-105.0911474 39.5952053, -105.0911079 39.5952053)",
+ "properties": {
+ "laneId": 5,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 7,
+ "geometry": "LINESTRING (-105.0911443 39.5951332, -105.0911017 39.5951356)",
+ "properties": {
+ "laneId": 7,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 2,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 12,
+ "geometry": "LINESTRING (-105.0915234 39.5950941, -105.0915234 39.5950602)",
+ "properties": {
+ "laneId": 12,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 13,
+ "geometry": "LINESTRING (-105.0915804 39.5950941, -105.0915796 39.595059, -105.0915796 39.595059, -105.0915796 39.5950596)",
+ "properties": {
+ "laneId": 13,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 4,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 10,
+ "geometry": "LINESTRING (-105.0913299 39.5950922, -105.09133 39.5944158, -105.0913348 39.5939413, -105.0913368 39.592921, -105.0913348 39.5923866, -105.0913348 39.5923866, -105.0913356 39.592386)",
+ "properties": {
+ "laneId": 10,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 9,
+ "geometry": "LINESTRING (-105.0912849 39.5950912, -105.0912838 39.5946624, -105.0912861 39.5940862, -105.0912901 39.5933704, -105.0912882 39.5923858)",
+ "properties": {
+ "laneId": 9,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 27,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 6,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 11,
+ "geometry": "LINESTRING (-105.0913713 39.5950916, -105.091375 39.5944888, -105.0913568 39.5942534)",
+ "properties": {
+ "laneId": 11,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 18,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 1,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 8,
+ "geometry": "LINESTRING (-105.0912303 39.5950889, -105.0912421 39.5949129, -105.0912427 39.5942475, -105.0912568 39.5941003)",
+ "properties": {
+ "laneId": 8,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 3,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 7,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 15,
+ "geometry": "LINESTRING (-105.0916931 39.5951733, -105.0927839 39.5951756, -105.0941732 39.5951722, -105.0952027 39.5951734)",
+ "properties": {
+ "laneId": 15,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 16,
+ "geometry": "LINESTRING (-105.0916852 39.5952059, -105.0931135 39.5952073, -105.0944406 39.595204, -105.0952041 39.5952041)",
+ "properties": {
+ "laneId": 16,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 8,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 17,
+ "geometry": "LINESTRING (-105.0916853 39.5952393, -105.0927239 39.5952377, -105.0941207 39.5952375, -105.0943034 39.5952213)",
+ "properties": {
+ "laneId": 17,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 26,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 3,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 14,
+ "geometry": "LINESTRING (-105.0916926 39.5951407, -105.0940224 39.5951414, -105.095203 39.5951408)",
+ "properties": {
+ "laneId": 14,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 5,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 18,
+ "geometry": "LINESTRING (-105.0916766 39.595308, -105.0917443 39.5953067)",
+ "properties": {
+ "laneId": 18,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 19,
+ "geometry": "LINESTRING (-105.0916758 39.5953365, -105.0917363 39.5953365)",
+ "properties": {
+ "laneId": 19,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 20,
+ "geometry": "LINESTRING (-105.0916734 39.5953755, -105.0917299 39.5953755)",
+ "properties": {
+ "laneId": 20,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 6,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 23,
+ "geometry": "LINESTRING (-105.091519 39.5954362, -105.0914927 39.5965421, -105.091488 39.5974092, -105.0914843 39.5981324, -105.0914843 39.5981324, -105.0914851 39.5981349)",
+ "properties": {
+ "laneId": 23,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 12,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 22,
+ "geometry": "LINESTRING (-105.0915548 39.5954372, -105.0915441 39.59638, -105.0915337 39.5974224, -105.0915281 39.5981345)",
+ "properties": {
+ "laneId": 22,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 13,
+ "maneuver": {
+ "maneuverStraightAllowed": true,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 2,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 21,
+ "geometry": "LINESTRING (-105.0916048 39.5954391, -105.0916029 39.5957255, -105.0916004 39.5962647, -105.0915885 39.5966976, -105.0915786 39.5977599, -105.0915764 39.5981344)",
+ "properties": {
+ "laneId": 21,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 20,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": false,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": true,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 24,
+ "geometry": "LINESTRING (-105.0914747 39.5954382, -105.0914714 39.5958506, -105.0914611 39.596192, -105.0914778 39.5963599)",
+ "properties": {
+ "laneId": 24,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 6,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 25,
+ "geometry": "LINESTRING (-105.0914371 39.5954371, -105.0914355 39.5958506, -105.0914461 39.596052)",
+ "properties": {
+ "laneId": 25,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 0,
+ "ingressApproach": 7,
+ "ingressPath": true,
+ "egressPath": false,
+ "maneuvers": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ },
+ "connectsTo": [
+ {
+ "connectingLane": {
+ "lane": 5,
+ "maneuver": {
+ "maneuverStraightAllowed": false,
+ "maneuverNoStoppingAllowed": false,
+ "goWithHalt": false,
+ "maneuverLeftAllowed": true,
+ "maneuverUTurnAllowed": false,
+ "maneuverLeftTurnOnRedAllowed": false,
+ "reserved1": false,
+ "maneuverRightAllowed": false,
+ "maneuverLaneChangeAllowed": false,
+ "yieldAllwaysRequired": false,
+ "maneuverRightTurnOnRedAllowed": false,
+ "caution": false
+ }
+ },
+ "signalGroup": 5,
+ "connectionID": 1
+ }
+ ]
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 26,
+ "geometry": "LINESTRING (-105.0913276 39.5954361, -105.0913284 39.5954678)",
+ "properties": {
+ "laneId": 26,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 27,
+ "geometry": "LINESTRING (-105.0912831 39.5954348, -105.0912839 39.5954647)",
+ "properties": {
+ "laneId": 27,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ },
+ {
+ "type": "Feature",
+ "id": 28,
+ "geometry": "LINESTRING (-105.0912264 39.5954336, -105.091228 39.5954647, -105.091228 39.5954653)",
+ "properties": {
+ "laneId": 28,
+ "laneType": {
+ "vehicle": {
+ "isVehicleRevocableLane": false,
+ "isVehicleFlyOverLane": false,
+ "permissionOnRequest": false,
+ "hasIRbeaconCoverage": false,
+ "restrictedToBusUse": false,
+ "restrictedToTaxiUse": false,
+ "restrictedFromPublicUse": false,
+ "hovLaneUseOnly": false
+ }
+ },
+ "sharedWith": {
+ "busVehicleTraffic": false,
+ "trackedVehicleTraffic": false,
+ "individualMotorizedVehicleTraffic": false,
+ "taxiVehicleTraffic": false,
+ "overlappingLaneDescriptionProvided": false,
+ "cyclistVehicleTraffic": false,
+ "otherNonMotorizedTrafficTypes": false,
+ "multipleLanesTreatedAsOneLane": false,
+ "pedestrianTraffic": false,
+ "pedestriansTraffic": false
+ },
+ "egressApproach": 8,
+ "ingressApproach": 0,
+ "ingressPath": false,
+ "egressPath": true
+ }
+ }
+ ]
+ },
+ "connectingLanesFeatureCollection": {
+ "type": "FeatureCollection",
+ "features": [
+ {
+ "type": "Feature",
+ "id": "2-19",
+ "geometry": "LINESTRING (-105.0911523 39.5953376, -105.0916758 39.5953365)",
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 2,
+ "egressLaneId": 19
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "3-18",
+ "geometry": "LINESTRING (-105.0911527 39.5953113, -105.0916766 39.595308)",
+ "properties": {
+ "signalGroupId": 4,
+ "ingressLaneId": 3,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "1-28",
+ "geometry": "LINESTRING (-105.0911535 39.5953745, -105.0912264 39.5954336)",
+ "properties": {
+ "ingressLaneId": 1,
+ "egressLaneId": 28
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "4-12",
+ "geometry": "LINESTRING (-105.0911537 39.5952537, -105.0915234 39.5950941)",
+ "properties": {
+ "signalGroupId": 7,
+ "ingressLaneId": 4,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "10-26",
+ "geometry": "LINESTRING (-105.0913299 39.5950922, -105.0913276 39.5954361)",
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 10,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "9-27",
+ "geometry": "LINESTRING (-105.0912849 39.5950912, -105.0912831 39.5954348)",
+ "properties": {
+ "signalGroupId": 6,
+ "ingressLaneId": 9,
+ "egressLaneId": 27
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "11-18",
+ "geometry": "LINESTRING (-105.0913713 39.5950916, -105.0916766 39.595308)",
+ "properties": {
+ "signalGroupId": 1,
+ "ingressLaneId": 11,
+ "egressLaneId": 18
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "8-7",
+ "geometry": "LINESTRING (-105.0912303 39.5950889, -105.0911443 39.5951332)",
+ "properties": {
+ "ingressLaneId": 8,
+ "egressLaneId": 7
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "15-6",
+ "geometry": "LINESTRING (-105.0916931 39.5951733, -105.0911474 39.5951732)",
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 15,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "16-5",
+ "geometry": "LINESTRING (-105.0916852 39.5952059, -105.0911474 39.5952053)",
+ "properties": {
+ "signalGroupId": 8,
+ "ingressLaneId": 16,
+ "egressLaneId": 5
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "17-26",
+ "geometry": "LINESTRING (-105.0916853 39.5952393, -105.0913276 39.5954361)",
+ "properties": {
+ "signalGroupId": 3,
+ "ingressLaneId": 17,
+ "egressLaneId": 26
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "14-13",
+ "geometry": "LINESTRING (-105.0916926 39.5951407, -105.0915804 39.5950941)",
+ "properties": {
+ "ingressLaneId": 14,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "23-12",
+ "geometry": "LINESTRING (-105.091519 39.5954362, -105.0915234 39.5950941)",
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 23,
+ "egressLaneId": 12
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "22-13",
+ "geometry": "LINESTRING (-105.0915548 39.5954372, -105.0915804 39.5950941)",
+ "properties": {
+ "signalGroupId": 2,
+ "ingressLaneId": 22,
+ "egressLaneId": 13
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "21-20",
+ "geometry": "LINESTRING (-105.0916048 39.5954391, -105.0916734 39.5953755)",
+ "properties": {
+ "ingressLaneId": 21,
+ "egressLaneId": 20
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "24-6",
+ "geometry": "LINESTRING (-105.0914747 39.5954382, -105.0911474 39.5951732)",
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 24,
+ "egressLaneId": 6
+ }
+ },
+ {
+ "type": "Feature",
+ "id": "25-5",
+ "geometry": "LINESTRING (-105.0914371 39.5954371, -105.0911474 39.5952053)",
+ "properties": {
+ "signalGroupId": 5,
+ "ingressLaneId": 25,
+ "egressLaneId": 5
+ }
+ }
+ ]
+ },
+ "properties": {
+ "schemaVersion": 1,
+ "messageType": "MAP",
+ "odeReceivedAt": "2025-02-01T00:50:49.19Z",
+ "originIp": "172.20.0.1",
+ "intersectionId": 12110,
+ "msgIssueRevision": 0,
+ "revision": 0,
+ "refPoint": {
+ "latitude": 39.5952649,
+ "longitude": -105.0914122,
+ "elevation": 1677
+ },
+ "cti4501Conformant": false,
+ "laneWidth": 366,
+ "mapSource": "RSU",
+ "timeStamp": "2025-02-01T00:50:49.19Z"
+ }
+ }
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference.json b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference.json
new file mode 100644
index 0000000..f781ea3
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/json/processed_map_wkt/sample.processed_map_wkt-reference.json
@@ -0,0 +1 @@
+{"mapFeatureCollection":{"type":"FeatureCollection","features":[{"type":"Feature","id":2,"geometry":"LINESTRING (-105.0911523 39.5953376, -105.0899239 39.5953231, -105.0896005 39.5953332, -105.0888831 39.595317, -105.088108 39.5953159, -105.0876637 39.5953153)","properties":{"laneId":2,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":1,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":19,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":4,"connectionID":1}]}},{"type":"Feature","id":3,"geometry":"LINESTRING (-105.0911527 39.5953113, -105.0908101 39.5953039, -105.0900791 39.5952962, -105.0896801 39.5952874, -105.0888781 39.5952839, -105.0885678 39.5952789, -105.0880704 39.5952849, -105.0876638 39.5952849)","properties":{"laneId":3,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":1,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":18,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":4,"connectionID":1}]}},{"type":"Feature","id":1,"geometry":"LINESTRING (-105.0911535 39.5953745, -105.0899328 39.5953544, -105.0897165 39.5953447)","properties":{"laneId":1,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":1,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":28,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"type":"Feature","id":4,"geometry":"LINESTRING (-105.0911537 39.5952537, -105.0903143 39.5952555, -105.0902511 39.5952591, -105.0900995 39.5952797)","properties":{"laneId":4,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":1,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":12,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":7,"connectionID":1}]}},{"type":"Feature","id":6,"geometry":"LINESTRING (-105.0911474 39.5951732, -105.0911048 39.5951738)","properties":{"laneId":6,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":2,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":5,"geometry":"LINESTRING (-105.0911474 39.5952053, -105.0911079 39.5952053)","properties":{"laneId":5,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":2,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":7,"geometry":"LINESTRING (-105.0911443 39.5951332, -105.0911017 39.5951356)","properties":{"laneId":7,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":2,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":12,"geometry":"LINESTRING (-105.0915234 39.5950941, -105.0915234 39.5950602)","properties":{"laneId":12,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":4,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":13,"geometry":"LINESTRING (-105.0915804 39.5950941, -105.0915796 39.595059, -105.0915796 39.595059, -105.0915796 39.5950596)","properties":{"laneId":13,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":4,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":10,"geometry":"LINESTRING (-105.0913299 39.5950922, -105.09133 39.5944158, -105.0913348 39.5939413, -105.0913368 39.592921, -105.0913348 39.5923866, -105.0913348 39.5923866, -105.0913356 39.592386)","properties":{"laneId":10,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":3,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":26,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":6,"connectionID":1}]}},{"type":"Feature","id":9,"geometry":"LINESTRING (-105.0912849 39.5950912, -105.0912838 39.5946624, -105.0912861 39.5940862, -105.0912901 39.5933704, -105.0912882 39.5923858)","properties":{"laneId":9,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":3,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":27,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":6,"connectionID":1}]}},{"type":"Feature","id":11,"geometry":"LINESTRING (-105.0913713 39.5950916, -105.091375 39.5944888, -105.0913568 39.5942534)","properties":{"laneId":11,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":3,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":18,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":1,"connectionID":1}]}},{"type":"Feature","id":8,"geometry":"LINESTRING (-105.0912303 39.5950889, -105.0912421 39.5949129, -105.0912427 39.5942475, -105.0912568 39.5941003)","properties":{"laneId":8,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":3,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":7,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"type":"Feature","id":15,"geometry":"LINESTRING (-105.0916931 39.5951733, -105.0927839 39.5951756, -105.0941732 39.5951722, -105.0952027 39.5951734)","properties":{"laneId":15,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":5,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":6,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":8,"connectionID":1}]}},{"type":"Feature","id":16,"geometry":"LINESTRING (-105.0916852 39.5952059, -105.0931135 39.5952073, -105.0944406 39.595204, -105.0952041 39.5952041)","properties":{"laneId":16,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":5,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":5,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":8,"connectionID":1}]}},{"type":"Feature","id":17,"geometry":"LINESTRING (-105.0916853 39.5952393, -105.0927239 39.5952377, -105.0941207 39.5952375, -105.0943034 39.5952213)","properties":{"laneId":17,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":5,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":26,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":3,"connectionID":1}]}},{"type":"Feature","id":14,"geometry":"LINESTRING (-105.0916926 39.5951407, -105.0940224 39.5951414, -105.095203 39.5951408)","properties":{"laneId":14,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":5,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":13,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"type":"Feature","id":18,"geometry":"LINESTRING (-105.0916766 39.595308, -105.0917443 39.5953067)","properties":{"laneId":18,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":6,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":19,"geometry":"LINESTRING (-105.0916758 39.5953365, -105.0917363 39.5953365)","properties":{"laneId":19,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":6,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":20,"geometry":"LINESTRING (-105.0916734 39.5953755, -105.0917299 39.5953755)","properties":{"laneId":20,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":6,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":23,"geometry":"LINESTRING (-105.091519 39.5954362, -105.0914927 39.5965421, -105.091488 39.5974092, -105.0914843 39.5981324, -105.0914843 39.5981324, -105.0914851 39.5981349)","properties":{"laneId":23,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":7,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":12,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":2,"connectionID":1}]}},{"type":"Feature","id":22,"geometry":"LINESTRING (-105.0915548 39.5954372, -105.0915441 39.59638, -105.0915337 39.5974224, -105.0915281 39.5981345)","properties":{"laneId":22,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":7,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":13,"maneuver":{"maneuverStraightAllowed":true,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":2,"connectionID":1}]}},{"type":"Feature","id":21,"geometry":"LINESTRING (-105.0916048 39.5954391, -105.0916029 39.5957255, -105.0916004 39.5962647, -105.0915885 39.5966976, -105.0915786 39.5977599, -105.0915764 39.5981344)","properties":{"laneId":21,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":7,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":20,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":false,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":true,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"connectionID":1}]}},{"type":"Feature","id":24,"geometry":"LINESTRING (-105.0914747 39.5954382, -105.0914714 39.5958506, -105.0914611 39.596192, -105.0914778 39.5963599)","properties":{"laneId":24,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":7,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":6,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":5,"connectionID":1}]}},{"type":"Feature","id":25,"geometry":"LINESTRING (-105.0914371 39.5954371, -105.0914355 39.5958506, -105.0914461 39.596052)","properties":{"laneId":25,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":0,"ingressApproach":7,"ingressPath":true,"egressPath":false,"maneuvers":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false},"connectsTo":[{"connectingLane":{"lane":5,"maneuver":{"maneuverStraightAllowed":false,"maneuverNoStoppingAllowed":false,"goWithHalt":false,"maneuverLeftAllowed":true,"maneuverUTurnAllowed":false,"maneuverLeftTurnOnRedAllowed":false,"reserved1":false,"maneuverRightAllowed":false,"maneuverLaneChangeAllowed":false,"yieldAllwaysRequired":false,"maneuverRightTurnOnRedAllowed":false,"caution":false}},"signalGroup":5,"connectionID":1}]}},{"type":"Feature","id":26,"geometry":"LINESTRING (-105.0913276 39.5954361, -105.0913284 39.5954678)","properties":{"laneId":26,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":8,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":27,"geometry":"LINESTRING (-105.0912831 39.5954348, -105.0912839 39.5954647)","properties":{"laneId":27,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":8,"ingressApproach":0,"ingressPath":false,"egressPath":true}},{"type":"Feature","id":28,"geometry":"LINESTRING (-105.0912264 39.5954336, -105.091228 39.5954647, -105.091228 39.5954653)","properties":{"laneId":28,"laneType":{"vehicle":{"isVehicleRevocableLane":false,"isVehicleFlyOverLane":false,"permissionOnRequest":false,"hasIRbeaconCoverage":false,"restrictedToBusUse":false,"restrictedToTaxiUse":false,"restrictedFromPublicUse":false,"hovLaneUseOnly":false}},"sharedWith":{"busVehicleTraffic":false,"trackedVehicleTraffic":false,"individualMotorizedVehicleTraffic":false,"taxiVehicleTraffic":false,"overlappingLaneDescriptionProvided":false,"cyclistVehicleTraffic":false,"otherNonMotorizedTrafficTypes":false,"multipleLanesTreatedAsOneLane":false,"pedestrianTraffic":false,"pedestriansTraffic":false},"egressApproach":8,"ingressApproach":0,"ingressPath":false,"egressPath":true}}]},"connectingLanesFeatureCollection":{"type":"FeatureCollection","features":[{"type":"Feature","id":"2-19","geometry":"LINESTRING (-105.0911523 39.5953376, -105.0916758 39.5953365)","properties":{"signalGroupId":4,"ingressLaneId":2,"egressLaneId":19}},{"type":"Feature","id":"3-18","geometry":"LINESTRING (-105.0911527 39.5953113, -105.0916766 39.595308)","properties":{"signalGroupId":4,"ingressLaneId":3,"egressLaneId":18}},{"type":"Feature","id":"1-28","geometry":"LINESTRING (-105.0911535 39.5953745, -105.0912264 39.5954336)","properties":{"ingressLaneId":1,"egressLaneId":28}},{"type":"Feature","id":"4-12","geometry":"LINESTRING (-105.0911537 39.5952537, -105.0915234 39.5950941)","properties":{"signalGroupId":7,"ingressLaneId":4,"egressLaneId":12}},{"type":"Feature","id":"10-26","geometry":"LINESTRING (-105.0913299 39.5950922, -105.0913276 39.5954361)","properties":{"signalGroupId":6,"ingressLaneId":10,"egressLaneId":26}},{"type":"Feature","id":"9-27","geometry":"LINESTRING (-105.0912849 39.5950912, -105.0912831 39.5954348)","properties":{"signalGroupId":6,"ingressLaneId":9,"egressLaneId":27}},{"type":"Feature","id":"11-18","geometry":"LINESTRING (-105.0913713 39.5950916, -105.0916766 39.595308)","properties":{"signalGroupId":1,"ingressLaneId":11,"egressLaneId":18}},{"type":"Feature","id":"8-7","geometry":"LINESTRING (-105.0912303 39.5950889, -105.0911443 39.5951332)","properties":{"ingressLaneId":8,"egressLaneId":7}},{"type":"Feature","id":"15-6","geometry":"LINESTRING (-105.0916931 39.5951733, -105.0911474 39.5951732)","properties":{"signalGroupId":8,"ingressLaneId":15,"egressLaneId":6}},{"type":"Feature","id":"16-5","geometry":"LINESTRING (-105.0916852 39.5952059, -105.0911474 39.5952053)","properties":{"signalGroupId":8,"ingressLaneId":16,"egressLaneId":5}},{"type":"Feature","id":"17-26","geometry":"LINESTRING (-105.0916853 39.5952393, -105.0913276 39.5954361)","properties":{"signalGroupId":3,"ingressLaneId":17,"egressLaneId":26}},{"type":"Feature","id":"14-13","geometry":"LINESTRING (-105.0916926 39.5951407, -105.0915804 39.5950941)","properties":{"ingressLaneId":14,"egressLaneId":13}},{"type":"Feature","id":"23-12","geometry":"LINESTRING (-105.091519 39.5954362, -105.0915234 39.5950941)","properties":{"signalGroupId":2,"ingressLaneId":23,"egressLaneId":12}},{"type":"Feature","id":"22-13","geometry":"LINESTRING (-105.0915548 39.5954372, -105.0915804 39.5950941)","properties":{"signalGroupId":2,"ingressLaneId":22,"egressLaneId":13}},{"type":"Feature","id":"21-20","geometry":"LINESTRING (-105.0916048 39.5954391, -105.0916734 39.5953755)","properties":{"ingressLaneId":21,"egressLaneId":20}},{"type":"Feature","id":"24-6","geometry":"LINESTRING (-105.0914747 39.5954382, -105.0911474 39.5951732)","properties":{"signalGroupId":5,"ingressLaneId":24,"egressLaneId":6}},{"type":"Feature","id":"25-5","geometry":"LINESTRING (-105.0914371 39.5954371, -105.0911474 39.5952053)","properties":{"signalGroupId":5,"ingressLaneId":25,"egressLaneId":5}}]},"properties":{"schemaVersion":1,"messageType":"MAP","odeReceivedAt":"2025-01-31T23:50:49.19Z","originIp":"172.20.0.1","intersectionId":12110,"msgIssueRevision":0,"revision":0,"refPoint":{"latitude":39.5952649,"longitude":-105.0914122,"elevation":1677.0},"cti4501Conformant":false,"laneWidth":366,"mapSource":"RSU","timeStamp":"2025-01-31T23:50:49.19Z"}}
\ No newline at end of file
diff --git a/jpo-deduplicator/src/test/resources/logback-test.xml b/jpo-deduplicator/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..cd07f49
--- /dev/null
+++ b/jpo-deduplicator/src/test/resources/logback-test.xml
@@ -0,0 +1,11 @@
+
+
+
+ %msg%n
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jpo-utils b/jpo-utils
new file mode 160000
index 0000000..8a9d961
--- /dev/null
+++ b/jpo-utils
@@ -0,0 +1 @@
+Subproject commit 8a9d96122bd33ddcff57880ed1e08ff9bdcf0aa1
diff --git a/sample.env b/sample.env
new file mode 100644
index 0000000..912cfb5
--- /dev/null
+++ b/sample.env
@@ -0,0 +1,62 @@
+### COMMON variables - START ###
+# (Required) The IP address of Docker host machine which can be found by running "ifconfig"
+# Hint: look for "inet addr:" within "eth0" or "en0" for OSX
+
+
+# Set the HOST IP of where the containers are running
+DOCKER_HOST_IP=
+KAFKA_BOOTSTRAP_SERVERS=${DOCKER_HOST_IP}:9092
+
+# GitHub properties for pulling the latest version of the JPO-ODE
+# Required for building the deduplicator. Documentation: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry#authenticating-to-github-packages
+MAVEN_GITHUB_TOKEN=
+MAVEN_GITHUB_ORG=usdot-jpo-ode
+
+
+# Docker compose restart policy: https://docs.docker.com/engine/containers/start-containers-automatically/
+RESTART_POLICY="on-failure:3"
+
+# Available profiles:
+# - all
+# - deduplicator_base
+# - deduplicator
+# - deduplicator_full
+# - deduplicator
+# - geojsonconverter
+# - ode
+# - adm
+#
+# All profiles from the jpo-utils repo are also allowed
+# Example: COMPOSE_PROFILES=kafka,kafka_ui,kafka_setup, deduplicator_full
+COMPOSE_PROFILES=kafka,kafka_ui,kafka_setup, deduplicator_full
+
+
+# Set to "CONFLUENT" if broker is a Confluent Cloud broker
+KAFKA_TYPE=
+
+# Set to actual Confluent Cloud access key and secret values for SASL authentication
+CONFLUENT_KEY=
+CONFLUENT_SECRET=
+
+KAFKA_TOPIC_CREATE_DEDUPLICATOR=true
+
+# Deduplicator Feature Flags
+ENABLE_PROCESSED_MAP_DEDUPLICATION=true
+ENABLE_PROCESSED_MAP_WKT_DEDUPLICATION=true
+ENABLE_ODE_MAP_DEDUPLICATION=true
+ENABLE_ODE_TIM_DEDUPLICATION=true
+ENABLE_ODE_RAW_ENCODED_TIM_DEDUPLICATION=true
+ENABLE_PROCESSED_SPAT_DEDUPLICATION=true
+ENABLE_ODE_BSM_DEDUPLICATION=true
+
+
+# RocksDB Bounded Memory Config Properties
+# 128 MB = 134217728
+# 64 MB = 67108864
+# 16 MB = 16777216
+DEDUPLICATOR_ROCKSDB_TOTAL_OFF_HEAP_MEMORY=134217728
+DEDUPLICATOR_ROCKSDB_INDEX_FILTER_BLOCK_RATIO=0.1
+DEDUPLICATOR_ROCKSDB_TOTAL_MEMTABLE_MEMORY=67108864
+DEDUPLICATOR_ROCKSDB_BLOCK_SIZE=4096
+DEDUPLICATOR_ROCKSDB_N_MEMTABLES=2
+DEDUPLICATOR_ROCKSDB_MEMTABLE_SIZE=16777216
\ No newline at end of file